Skip to content

E31: Event-driven servicing #573

Description

@DavidCozens

Problem

The library tells integrators to drive SolidSyslog_Service() from a permanent loop with a fixed delay. That works but is wasteful: on an idle system it burns CPU/power polling for nothing, and on a backlog it sleeps between units of work when it should be cycling. Service() returns void, so the host has no way to know whether there is more to do, whether it should back off, or whether the store has wedged — it can only guess with a timer.

Everything the host needs to make that decision already exists inside Service(): the buffer drain knows whether it moved anything, the send step knows whether it failed, and the store knows whether it has unsent records and whether it is halted. We just throw that knowledge away by returning void.

Approach

Surface that state as a return value and let the integrator build whatever wake/sleep mechanism their OS offers — semaphore, task notification, auto-reset event, or plain sleep — in a thin wrapper around Log and Service. The library stays fully OS-agnostic: no new injected primitive, no vtable, no per-platform code. The entire change is Service()'s return type.

The host's loop becomes:

for (;;) {
    switch (SolidSyslog_Service(h)) {
        case SOLIDSYSLOG_SERVICE_READY:   break;                  /* loop now */
        case SOLIDSYSLOG_SERVICE_IDLE:    wait_for_log_signal();  /* until next Log */
        case SOLIDSYSLOG_SERVICE_BLOCKED: wait_with_backoff();    /* sender down */
        case SOLIDSYSLOG_SERVICE_HALTED:  handle_halt();          /* store wedged */
    }
}

Wake-on-Log is the integrator's wrapper signalling their own primitive right after SolidSyslog_Log() — the library never holds an OS handle. The status is purely an advisory wakeup hint; correctness comes from Service re-deriving state from the real buffer/store each call, so a missed or spurious signal is always safe.

Out of scope

  • Any OS-specific waitable/semaphore in the library.
  • Worked per-platform wrapper examples and prose — the upcoming documentation epic rewrites that material; this epic only documents the contract in the Service() header comment.
  • The latent "a HALTED store never drains itself even when the sender recovers" behaviour — separate fix if we decide it is wrong.

Stories

  • S31.01 — Service returns a four-state servicing status (IDLE / READY / BLOCKED / HALTED).

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicEpic issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions