Skip to main content

Module recorder

Module recorder 

Source
Expand description

Downstream consumer that records completed fills into the competition tables.

This is the ingestion side of competitions, decoupled from the websocket broadcast path. The recorder consumes a stream of [EngineMessage] and, for each OrderFilled, persists a competition fill.

§Source-agnostic by design

run takes a plain mpsc::UnboundedReceiver<EngineMessage>, so it does not care where the fill stream comes from. Today the runtime feeds it from the in-process engine EventBus (TOPIC_FILLS subscription). When the engine runs out-of-process (see the transport-evolution roadmap), the same recorder is fed by a NATS JetStream consumer instead, with no change here. Other downstream services (analytics, auditors) subscribe to the same stream the same way.

§Failure handling

A competition write failure is logged and metered but does NOT crash the engine node. The previous implementation recorded fills inline in the websocket forwarder and triggered a full process shutdown on failure, so a transient leaderboard DB error could take down trading. Fill recording is idempotent (record_competition_fill is ON CONFLICT (trade_id, wallet) DO NOTHING), so a dropped fill is safely re-recordable.

§Durability caveat (not yet a durable follower)

This consumes an in-memory event stream. Fills already written to competition_fill_events survive restart, but a fill emitted but not yet recorded when the node dies is NOT recovered: engine replay rebuilds engine state without re-emitting fills to the event bus. Closing that crash window requires making competition a durable external-follower projection that replays the fill stream from the journal/NATS at a recorded offset (tracked separately).

Structs§

CompetitionFillRecorder
Consumes the engine fill stream and records competition fills.

Traits§

CompetitionFillSink
Minimal sink the recorder depends on: persist one competition fill.