server

package
v0.16.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 38 Imported by: 0

Documentation

Overview

Package server is the loopback HTTP mux for the web UI and the API (specs/000-product/contracts/api.md). Reads are assembled from the SQLite mirror. Write-through endpoints call Jira and re-read the issue into the mirror. Credentials are needed for those writes and for fetching attachment bytes that are not already on disk.

The server has no authentication: `gadak serve` refuses a non-loopback bind instead. Personal-state endpoints therefore never answer 401/403.

Index

Constants

This section is empty.

Variables

View Source
var Version = "0.0.0-dev"

Version is the gadak release string exposed on GET settings/ under runtime. cmd/gadak should assign this from its ldflags version var at startup:

server.Version = version

Until that wiring lands, the default below is what the UI shows.

Functions

func DerivedInFlight added in v0.16.0

func DerivedInFlight() int64

DerivedInFlight is how many derived() rebuilds are running outside s.mu. Same shape as store.WriteBusyRetries: a cheap accessor, no logs.

func GuardBrowser added in v0.13.0

func GuardBrowser(next http.Handler) http.Handler

GuardBrowser wraps next so Host/Origin checks run before any route. Mount this on the top-level serve mux so routes registered outside Handler (/config.json, /healthz, /api/v1/workspaces, /w/) cannot skip the guard.

func WebConfig

func WebConfig(cfg *config.Config) ([]byte, error)

WebConfig renders the config document the UI fetches before mount (`GadakConfig` in web/src/lib/config.ts). Credentials never appear in it.

func WebConfigBase

func WebConfigBase(cfg *config.Config, prefix string) ([]byte, error)

WebConfigBase is WebConfig with APIBase/AuthBase prefixed (e.g. "/w/work" for a workspace mount). prefix has no trailing slash; empty means root bases.

Types

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler is the HTTP API plus optional update-check control. It implements http.Handler; mount it at "/api/".

func New

func New(db *store.DB, cfg *config.Config) *Handler

New returns the API handler. Mount it at "/api/" — the patterns below carry their full paths, so nothing strips a prefix.

func NewWithCache

func NewWithCache(db *store.DB, cfg *config.Config, cache *attachcache.Cache) *Handler

NewWithCache is New plus an attachment byte cache. `gadak serve` passes one rooted under GADAK_HOME; tests pass nil when they do not exercise attachments.

func NewWorkspace

func NewWorkspace(db *store.DB, cfg *config.Config, cache *attachcache.Cache, profile string) *Handler

NewWorkspace is NewWithCache bound to a named profile (for /w/<name>/ mounts). profile is used for runtime paths and display; it does not re-read global config.

func (*Handler) BindOriginHandler added in v0.16.0

func (h *Handler) BindOriginHandler(next http.Handler)

BindOriginHandler pins the passthrough target. Tests use it so they can evict origin.live (simulating a second process) without reconstructing a second issuetap graph on the next request.

func (*Handler) CheckNow added in v0.16.0

func (h *Handler) CheckNow(ctx context.Context, cacheDir string) UpdateStatus

CheckNow bypasses the 24h disk cache, hits GitHub once, and records the result for GET update/ and for bootstrap/delta. Background checks stay silent; this path is the one that reports current / error / dev.

func (*Handler) Close added in v0.16.0

func (h *Handler) Close() error

Close is Shutdown with a 3s bound — the same window cmd/gadak/serve.go uses for http.Server.Shutdown.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

func (*Handler) SetSyncStarter

func (h *Handler) SetSyncStarter(f func())

SetSyncStarter registers a function that starts the background sync loop after the first credential is saved via onboarding connect. Fired at most once. cmdServe registers this when serve starts without a credential.

func (*Handler) Shutdown added in v0.16.0

func (h *Handler) Shutdown(ctx context.Context) error

Shutdown cancels background startSyncJob work and waits for those goroutines to return, or until ctx is done. A timed-out wait returns ctx.Err(); the job may still be running and still hold a database connection. Idempotent.

Returning from the job goroutine is not enough: database/sql rolls a cancelled Tx back from a helper goroutine (Tx.awaitDone), and that helper can still hold the pool connection after runSyncJob has returned. Waiting for InUse==0 is waiting for that writer, which is the WAL leak GDK-270 actually is.

func (*Handler) SnapshotSync added in v0.16.0

func (h *Handler) SnapshotSync() progressResponse

SnapshotSync is the debug document for "what background work is running right now": the same one-shot job + activity picture that GET /api/v1/issues/sync/progress/ already returns. No new endpoint — that GET already carries it; this is the in-process form.

func (*Handler) StartUpdateCheck

func (h *Handler) StartUpdateCheck(ctx context.Context, cacheDir string)

StartUpdateCheck runs a GitHub release lookup immediately and every 24h. Results feed latest_version / release_url on bootstrap and delta when the running build is older. Records cacheDir even when disabled so a later user-initiated CheckNow still knows where the file lives. The background loop is a no-op when cfg.UpdateCheckEnabled() is false. Safe with no credential (Jira-independent). Background errors are silent.

func (*Handler) SyncActivityHooks

func (h *Handler) SyncActivityHooks() (phase func(string), progress func(fetched, changed int))

SyncActivityHooks returns the Phase and Progress callbacks a background watch loop should report through, so the UI can say what the mirror is fetching and how far along. Safe for concurrent use; nil Handler returns nil funcs (callers pass them straight into sync.Options).

type UpdateStatus added in v0.16.0

type UpdateStatus struct {
	Current         string `json:"current"`
	Latest          string `json:"latest,omitempty"`
	URL             string `json:"release_url,omitempty"`
	Notes           string `json:"release_notes,omitempty"`
	NotesLen        int    `json:"release_notes_len"`
	CheckedAt       string `json:"checked_at,omitempty"`
	Newer           bool   `json:"newer,omitempty"`
	Status          string `json:"status,omitempty"` // newer|current|error|dev — this CheckNow
	Error           string `json:"error,omitempty"`
	LastUserCheckAt string `json:"last_user_check_at,omitempty"`
	LastUserStatus  string `json:"last_user_status,omitempty"`
}

UpdateStatus is GET/POST update/ and CheckNow: what the server currently knows about the latest published release, plus the outcome of a user-initiated check when one has run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL