Engineering case study
triggerd
A Go daemon that turns ntfy notifications into allowlisted tasks on Linux, macOS, and Windows. An outbound subscription receives events; the operating system manages the work.
Context
I wanted a small way to trigger a task, such as regenerating a résumé, from a notification. The design keeps task permissions, dependencies, and logs with the existing service manager. triggerd connects the notification to a configured action through a narrow, inspectable execution path.
System design
- ReceiveAn outbound ntfy stream delivers a notification.
- ValidateDecode the payload and resolve an allowlisted action.
- DispatchApply queue, concurrency, and timeout policies.
- TriggerAsk the platform service manager to start the task.
Key decisions
Keep authority in configuration
The message selects an action name. Configuration defines its executor and target. Strict JSON decoding rejects unknown fields and invalid names before work enters the queue. The OS-task executor builds argument arrays and ignores incoming parameters, keeping network input out of the command line.
Make overload visible
A bounded queue and worker pool control pending and active calls. Queue overflow is dropped, logged, and counted. Per-action guards reject overlapping executor calls, and each call receives a timeout. Shutdown discards waiting requests while giving active calls a configurable grace period.
Retry the connection deliberately
The ntfy source reconnects with exponential backoff and jitter. A read-idle watchdog detects stalled streams, and a recent-message window suppresses replayed IDs. Failed actions are left to the operator because repeating a task may repeat its side effects. Invalid credentials stop the daemon with an actionable failure.
Isolate platform behavior
The core pipeline separates event sources, decoding, action lookup, and execution. Small platform planners handle systemd, launchd, and Task Scheduler. An injectable command runner lets tests check commands and errors without starting real services. The same planning code supports configuration validation and dry runs.
Carry the platform split into delivery
GitHub Actions runs build, vet, and race-detector tests across Linux, macOS, and Windows. The release workflow cross-compiles six platform targets and attaches binaries with SHA-256 checksums to versioned releases after the required checks complete.
Operation & limits
YAML configuration defines sources, actions, and dispatcher limits. Credentials can come from environment variables, and structured logs record execution outcomes. Deployment examples cover systemd services, launchd agents, and Windows scheduled tasks. The CLI offers configuration validation and a dry run through the event pipeline.
References
Source code and documentation for a closer look.