Task: Put the coalesced frames on the stream

Table of Contents

This page documents a task in the Stream the changes as they happen story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

A change recorded in the coalescer reaches every open stream as one event-stream message per entity.

2. Status

Field Value
State DONE
Parent story Stream the changes as they happen
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-31

3. Acceptance

  • [X] A coalesced frame becomes one event-stream message naming the entity and carrying its identifiers.
  • [X] A pump over a window reaches every open stream and only the ones open.
  • [X] A window with nothing in it writes nothing.

4. Plan

The message states the entity as its event name, so a client can subscribe by name instead of parsing the payload to learn what changed, and the data is JSON with the tenant, the party and the identifiers. It is written here rather than by a codec because it is the envelope the stream states, not a domain object.

The pump is a function rather than a thread, so a case can pump one window and read what a subscriber got. The timer that calls it, and the subscription that records into the coalescer, are the next task.

5. Measurements

What Value Command Commit
Pump cases 5 cases, 12 assertions, all passing ./ores.http.core.tests "[change_pump]" this branch
Whole ores.http.core suite 33 cases, 150 assertions, all passing ./ores.http.core.tests this branch

6. Notes

  • The helper that quotes a string had to be renamed: as quoted it collided with std::quoted by argument-dependent lookup, and the compiler's complaint named a type no one had written.
  • A stream that has ended is not given the next window, because the publish drops closed subscriptions. A hub that kept them would grow one dead entry per connection.

7. Result

The path from a recorded change to a client is complete in code: record, drain, format, fan out. What is missing is the source of the events and the timer that drives the window, and the story says so.

Emacs 29.3 (Org mode 9.6.15)