No results
1
Daemon Mode
Virgil edited this page 2026-02-23 04:54:00 +00:00
Daemon Mode
Execution Modes
mode := cli.DetectMode()
// cli.ModeInteractive — TTY attached, colours enabled
// cli.ModePipe — stdout piped, colours disabled
// cli.ModeDaemon — CORE_DAEMON=1, log-only output
cli.IsTTY() // stdout is terminal?
cli.IsStdinTTY() // stdin is terminal?
Simple Daemon
func runDaemon(cmd *cli.Command, args []string) error {
ctx := cli.Context() // Cancelled on SIGINT/SIGTERM
// ... start work ...
return cli.Run(ctx) // Blocks until signal
}
Full Daemon with Health Checks
daemon := cli.NewDaemon(cli.DaemonOptions{
PIDFile: "/var/run/myapp.pid",
ShutdownTimeout: 30 * time.Second,
HealthAddr: ":9090",
HealthChecks: []cli.HealthCheck{checkDB},
})
if err := daemon.Start(); err != nil {
return err // "another instance is running (PID 1234)"
}
daemon.SetReady(true)
return daemon.Run(cli.Context()) // Blocks, handles shutdown
Health Endpoints
GET /health— Liveness (200 if server up, 503 if checks fail)GET /ready— Readiness (200 if ready, 503 if not)
PID File
pid := cli.NewPIDFile("/tmp/myapp.pid")
if err := pid.Acquire(); err != nil {
// "another instance is running (PID 1234)"
}
defer pid.Release()
Shutdown with Timeout
cli.Init(cli.Options{AppName: "worker"})
shutdown := cli.RunWithTimeout(30 * time.Second)
defer shutdown() // Replaces cli.Shutdown()
cli.Run(cli.Context())
Signal Handling
Built into the runtime — SIGINT/SIGTERM cancel cli.Context(). Optional SIGHUP for config reload:
cli.Init(cli.Options{
AppName: "daemon",
OnReload: func() error {
return reloadConfig()
},
})