App
Background Jobs
Register typed background jobs, enqueue work, and inspect job state.
Define jobs
GoLazy jobs are typed Go structs with JSON payloads. A job has a stable kind
and a Work method:
package importwhatsapp
import (
"context"
"sample_app/app/jobs/basejob"
)
type Job struct {
basejob.BaseJob
ImportID int64 `json:"import_id"`
}
func (*Job) Kind() string { return "imports.whatsapp" }
func (j *Job) Work(ctx context.Context) error {
// Load services from ctx and process j.ImportID.
return nil
}
Put the application base job in app/jobs/basejob/basejob.go:
package basejob
import "golazy.dev/lazyjobs"
type BaseJob struct {
lazyjobs.BaseJob
}
The app base package keeps concrete job packages from importing the registry package and avoids Go import cycles.
Register jobs
Register jobs from app/jobs/jobs.go:
package jobs
import (
"golazy.dev/lazyjobs"
"sample_app/app/jobs/importwhatsapp"
)
func DefinedJobs(runner *lazyjobs.JobRunner) {
runner.MustRegister(&importwhatsapp.Job{})
}
Wire the registry into lazyapp.Config.Jobs:
lazyapp.New(lazyapp.Config{
Name: "sample_app",
Drawer: Draw,
Public: app.Public,
Views: app.Views,
Dependencies: Dependencies,
Jobs: lazyjobs.Config{
Define: jobs.DefinedJobs,
},
})
When Jobs is configured and no backend is passed, GoLazy uses the bundled
in-memory backend. Applications that need durable work can pass their own
lazyjobs.Backend. PostgreSQL apps can use golazy.dev/pg/pgjobs and wire it
from the shared pool described in PostgreSQL.
Enqueue work
Resolve the runner from the request or service context:
runner, ok := lazyjobs.RunnerFromContext(ctx)
if !ok {
return errors.New("jobs are not configured")
}
_, err := runner.Enqueue(ctx, &importwhatsapp.Job{ImportID: importID})
return err
The runner serializes the job payload to JSON, stores it through the backend, and in v1 starts in-process workers with the application.
Inspect jobs
When jobs are configured, GoLazy registers a read-only GET /jobs endpoint on
the app control plane. It returns runner status, job definitions, state counts,
and recent jobs. In lazy development, the GoLazy panel proxies that endpoint
and shows the same data in the Jobs tab.
Production builds still follow normal control-plane exposure rules: use
CONTROL_PLANE_ADDR when job state should be available outside application
routes.