Embedding
Wakeplane is designed as a reusable primitive. You can embed the control plane directly in your Go application rather than running it as a separate daemon.
Basic embedding
Section titled “Basic embedding”package main
import ( "context" "log/slog"
"github.com/justyn-clark/wakeplane/internal/app")
func main() { cfg := app.Config{ DBPath: "./wakeplane.db", Addr: ":8080", Logger: slog.Default(), }
svc, err := app.New(cfg) if err != nil { log.Fatal(err) }
// Register workflow handlers before starting svc.RegisterWorkflow("my-workflow", func(ctx context.Context, payload []byte) error { // Your work here return nil })
ctx := context.Background() if err := svc.Start(ctx); err != nil { log.Fatal(err) }
// Block until signal <-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() svc.CloseContext(shutdownCtx)}Workflow handlers
Section titled “Workflow handlers”Workflow handlers must be registered before Start() is called. Dynamic or out-of-process loading is not supported in v0.1.
svc.RegisterWorkflow("name", func(ctx context.Context, payload []byte) error { // Respect ctx.Done() for cooperative cancellation select { case <-ctx.Done(): return ctx.Err() default: } // ... do work return nil})Handlers that ignore ctx.Done() are non-cooperative. The dispatcher enforces the run timeout and reports remaining active workers on shutdown.
Shutdown sequence
Section titled “Shutdown sequence”CloseContext drives structured shutdown:
- Cancel the run context (planner and dispatcher loops stop).
- Wait for the run loop goroutine to exit.
- Call
dispatcher.Shutdown(ctx)— cancels active execution contexts, waits for in-flight goroutines to drain. - Close the SQLite store.
Each phase emits structured logs. If the context deadline is exceeded, CloseContext returns context.DeadlineExceeded and the store is left open to avoid closing under active work.
Embedding contract
Section titled “Embedding contract”- Registering a workflow name that is already registered returns an error.
- The embedding application owns process lifecycle. Wakeplane does not call
os.Exit. - The HTTP API is available at the configured address while the service is running.
- Wakeplane does not own signal handling. Wire
os.Signalto context cancellation in the embedding application.
See also
Section titled “See also”examples/in the source repo — reference embedding examples- Reference: Storage — storage interface for custom store implementations
- Operations: Runbook — shutdown and drain logging