STREAM
STREAM = 'strata:journal'
Default stream key.
A journal backed by a Redis stream.
The database journal is always available and is the default. This one exists for the case that breaks it: a site whose write volume makes the journal table itself a contended resource. Two thirds of a Drupal site's captured operations are user access-timestamp churn, so a busy site appends tens of thousands of rows an hour to one table, and every one of those appends sits inside a web request.
A stream, not a list. XADD assigns a monotonic id server-side, which is the same property the
table's serial column provides and the reason two concurrent requests get a total order without
either taking a lock. A list would need a separate counter and a round trip to read it.
Ids are mapped to sequences, because the interface promises an integer sequence. A Redis stream
id is <milliseconds>-<counter>, which does not fit an int without losing the counter. The counter
is what orders two appends inside the same millisecond, so it cannot be dropped. The mapping keeps
both: the sequence is milliseconds * 1000 + counter, which is monotonic as long as fewer than a
thousand operations land in one millisecond - and at a thousand appends a millisecond the journal is
not the bottleneck.
Redis is not durable the way a database table is. An XADD acknowledged before the append-only
file is fsynced is lost on a hard kill. That is a real trade and it is the operator's to make: the
loss window is bounded by Redis's own appendfsync setting, and it is why this is not the default.
__construct(object $redis, string $stream = \self::STREAM) : mixed
Constructs a journal.
| object | $redis | A connected client exposing the stream commands: |
| string | $stream | The stream key. |
When the client does not expose the stream commands, which is what an older Redis client or a Predis instance looks like. Refusing here beats discovering it on the first capture.
append(\Drupal\strata\Journal\JournalOp $operation, ?string $payload = null) : \Drupal\strata\Journal\JournalOp
Appends an operation and its payload.
| \Drupal\strata\Journal\JournalOp | $operation | The operation to append. |
| ?string | $payload | The value the operation captured, or NULL for an operation that carries none. |
The operation as appended, carrying its assigned sequence.