camelot 0.3.1
A bug-fix release, and an important one if you run the daemon.
The daemon could spin a core. Left running (paused, overnight), it reached 100% CPU and stopped answering commands. Its GLib pump had paths that returned to the top of the loop with no yield point, starving every other fiber — including the one that answers the socket.
- Dispatch is now bounded: "iterate until nothing is ready" is not finite in general, because libatspi arms an idle source while draining its own queue.
- Watchers are retired when GLib stops polling an fd. A dead application's connection stays readable at EOF forever and would wake the pump for eternity — the likely trigger for an overnight run.
- Every path ends in a wait or a real 1 ms sleep, never
Fiber.yield: while the pump is runnable Crystal never runs its own event loop, so timer-based fibers would never wake. - Pausing now gates event resolution, so a paused daemon really does no work.
Measured over a minute: 0.67% CPU recording, 0.28% paused, responsive in both. A regression spec covers it: an always-ready GLib source must not stop a plain Crystal fiber from ticking.
Upgrade if you are running 0.3.0 as a service.