Перейти к основному содержимому
Эта страница ещё не переведена

Ниже показан английский оригинал.

Headers

Every delivery carries its sequence number, its shard and its partition key as headers, where the framework's per-key dispatch finds the key.

HeaderConstantValue
kinesis-sequence-numberSEQUENCE_HEADERthe record's sequence number on its shard, a decimal string too wide for an integer
kinesis-shard-idSHARD_HEADERthe shard the record was read from, such as shardId-000000000000
partition-keyPARTITION_KEY_HEADERthe record's partition key

The subscription writes the three headers from the record's own fields, next to the headers the producer wrote in the envelope. A handler reads them from ctx.headers(), as text with get_str. The sequence number and the shard name the same record that the Position key names.

The partition key under partition-key is the key the core's IncomingMessage::partition_key reports. So workers(n, by_key) runs the records of one key one after another on one lane, in the order the shard holds them, while records of other keys run beside them. A retry copy carries the delivery's headers, so it keeps the record's partition key.

Example​

The meter is each reading's partition key, so the readings of one meter are billed in order on four lanes.

use ruststream_kinesis::{PARTITION_KEY_HEADER, SEQUENCE_HEADER, SHARD_HEADER};

/// Bills each meter reading. The meter is the record's partition key, so the readings of one
/// meter run one after another on four lanes, and in the order the stream holds them.
#[subscriber(KinesisStream::new("meters"), workers(4, by_key))]
async fn bill(
reading: &Reading,
ctx: &mut Context<'_>,
Out(bills): Out<impl Publisher, Bills>,
) -> HandlerOutcome {
let headers = ctx.headers();
let (Some(meter), Some(shard), Some(sequence)) = (
headers.get_str(PARTITION_KEY_HEADER),
headers.get_str(SHARD_HEADER),
headers.get_str(SEQUENCE_HEADER),
) else {
return HandlerOutcome::drop();
};
tracing::info!(meter, shard, sequence, reading.kwh, "reading billed");
let charge = Bill {
meter: meter.to_owned(),
kwh: reading.kwh,
};
if bills.message(&charge).publish().await.is_err() {
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}