Skip to main content

Class: AuditRelay

Defined in: packages/audit-client/src/relay.ts:98

Publishes a module's outbox to the AUDIT stream, with Nats-Msg-Id = the record id.

One relay per module. The relay belongs to the module's pool and role; a process that hosts several modules runs one relay for each, so no module reads or writes another's outbox (09). Replicas of one module may run relays concurrently: FOR UPDATE SKIP LOCKED keeps them off each other's rows.

At-least-once, made idempotent. A row is marked published in the transaction that published it. A crash between the two republishes it with the same message id, which the stream's duplicate window absorbs, and the audit service's unique record id absorbs after that.

A publish failure never retires a row. A broker that is down, partitioned or slow is the case the outbox exists for: the row stays pending and is retried with a capped backoff for as long as it takes, so an outage of any length loses nothing and takes no record out of the chain's path. Only a row that cannot be read back as a valid record (recordOfRow refuses it: it was altered, or written by something that is not the client) is set aside as dead, logged, and counted by AuditRelay.depth so that readiness can fail on it. It could never be published, so retrying it is pointless.

The relay polls. It has no LISTEN: persistence offers no dedicated connection, so AuditRelay.nudge is how a caller who has just committed shortens the wait.

Constructors​

Constructor​

new AuditRelay(options): AuditRelay

Defined in: packages/audit-client/src/relay.ts:119

Parameters​

options​

AuditRelayOptions

Returns​

AuditRelay

Throws​

unknown_module.

Throws​

The module is not a listed publisher of the audit event in the permission table. Raised here, so a relay for a module that may not publish fails to start, not at the first record.

Methods​

depth()​

depth(): Promise<{ dead: number; pending: number; }>

Defined in: packages/audit-client/src/relay.ts:225

Returns​

Promise<{ dead: number; pending: number; }>

Rows waiting to be published and rows set aside as dead, for a gauge and for readiness. A non-zero dead is a record that will never reach the chain and needs an operator; pending is only a backlog.


drainOnce()​

drainOnce(): Promise<DrainResult>

Defined in: packages/audit-client/src/relay.ts:152

One pass: claims a batch, publishes it in write order and marks each row. A publish failure stops the pass at that row (the broker is the likely cause of the next one too), counts the attempt and leaves the rest for the next pass; the row stays pending however many times it fails.

Returns​

Promise<DrainResult>

What happened.

Throws​

The database failed; nothing was marked, so every row is retried.


nudge()​

nudge(): void

Defined in: packages/audit-client/src/relay.ts:239

Cuts the current wait short. Call it after committing a transaction that recorded.

Returns​

void


start()​

start(): void

Defined in: packages/audit-client/src/relay.ts:232

Starts the polling loop. Calling it twice is harmless.

Returns​

void


stop()​

stop(): Promise<void>

Defined in: packages/audit-client/src/relay.ts:248

Stops the loop after the pass in progress.

Returns​

Promise<void>

When the loop has ended.