Managed Goroutines
You should avoid starting a barego func() in a Copper application. Instead, use Lifecycle.Go; Copper recovers panics for you and will automatically wait for the goroutine to finish during graceful shutdown:
Long-Running Workers
For a worker loop, combineLifecycle.Go with Lifecycle.Shutdown(), which closes when the app begins shutting down:
pkg/telemetry/poller.go
A Dedicated Worker Binary
When background work outgrows the web process, you may give it its own binary. Add acmd/jobs directory with the same main.go/wire.go shape as cmd/app, wire the same app.WireModule, and start a runner instead of the HTTP server:
cmd/jobs/main.go
Run() error method (the copper.Runner interface). Both binaries share one dependency graph, and copper build compiles every target under cmd/, so deploying the worker is simply deploying another binary from the same codebase.
Work Tied to a Transaction
Sometimes background work should only happen if the surrounding database transaction commits, such as sending an email or publishing an event. In that case, register the work withquerier.OnCommit instead of acting immediately; if the transaction rolls back, the callback never runs. To learn more, see Transactions.
Reacting to Events
When one action should trigger several reactions, you may publish an event and let interested packages subscribe. See Pub/Sub.Scheduled Work
The simplest cron in a Copper app is an HTTP route. Add an/internal/... route that performs the work, and have your scheduler (crontab, Cloud Scheduler, Kubernetes CronJob) POST to it:
curl. However, you should keep /internal/ routes unexposed at the network layer, since the application does not authenticate them.