App

Background Jobs

Register typed background jobs, enqueue work, and inspect job state.

By Guillermo Alvarez - Published Updated

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.