Ramblings of an aging IT geek
← Ramblings of an aging IT geek
golang

a small go daemon, actually finished

I wrote and shipped a tiny single-purpose daemon in Go this weekend, and the pleasure was in how little it took to be done.

A code editor with a Go file open

I shipped a thing this weekend. Small, single-purpose, dull: a daemon that watches a directory and reconciles it against a remote, the sort of glue I would normally leave half-written in a scratch/ folder. This time I finished it, and the finishing was the point.

Go remains the right tool for this exact shape of problem. A for select loop over a ticker and a signal channel, a context threaded through so shutdown is clean, and that is the whole skeleton. No event loop framework, no dependency tree to audit.

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()

ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()

for {
	select {
	case <-ctx.Done():
		return
	case <-ticker.C:
		reconcile()
	}
}

go build gives me one static binary. I scp it to the box, drop in a fifteen-line systemd unit, systemctl enable --now, and it is running. No runtime to install, no virtualenv to rot. The thing that made it shipped rather than abandoned was deciding what it would not do. No config file, just flags. No plugins. No metrics endpoint, because nobody is going to scrape it. Every feature I left out was a reason it got finished. The best small tools are the ones you let stay small.