Skip to content

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.

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 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.

CloseContext drives structured shutdown:

  1. Cancel the run context (planner and dispatcher loops stop).
  2. Wait for the run loop goroutine to exit.
  3. Call dispatcher.Shutdown(ctx) — cancels active execution contexts, waits for in-flight goroutines to drain.
  4. 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.

  • 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.Signal to context cancellation in the embedding application.
  • examples/ in the source repo — reference embedding examples
  • Reference: Storage — storage interface for custom store implementations
  • Operations: Runbook — shutdown and drain logging