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

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

SchemaPrefetch

SchemaPrefetch resolves every registered subject at connect, which keeps the codecs' encode and decode free of I/O.

A codec is synchronous, and a registry lookup is not. The prefetch is the async half: every codec built from it, AvroCodec::registry or SchemaFramed::new, records its registered subjects on it. KafkaBroker::schema_prefetch attaches it, and the broker's connect resolves each subject before the app takes a delivery. On the consume path the prefetch resolves the writer schema that an arriving envelope names before the codec decodes the delivery, and leaves the payload as it arrived. A lookup that fails there is logged, and the decode that follows settles the delivery by the subscription's failure policy.

The registry appears twice in an app: once building the prefetch, once attaching it. A mount site never names it. Every codec comes from the one prefetch, and what varies per mount is the subject. A Router inside a broker scope overrides the scope's codec for the handlers it carries, by the usual codec cascade.

check_compatibility is on by default. At connect each registered type's schema is checked the way registering it would be, against the versions the subject's compatibility level names: the latest one, or every version under a _TRANSITIVE level. A model that has drifted from its subject stops the app, and the error carries the registry's own account of the difference. check_compatibility(false) turns the check off, for a registry whose level is NONE. A subject the registry does not hold is settled by MissingSubject.

The prefetch and the transcode are alternatives on one broker: the prefetch reads the envelope, and the transcode replaces it with JSON.

Example​

#[derive(Debug, PartialEq, Serialize, Deserialize, AvroSchema)]
struct Order {
id: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, AvroSchema, Outgoing)]
#[outgoing(name = "shipments")]
struct Shipment {
order: i64,
carrier: String,
}

#[subscriber("orders", reply)]
async fn ship(order: &Order) -> Shipment {
tracing::info!(order.id, "order shipped");
Shipment {
order: order.id,
carrier: "post".to_owned(),
}
}

fn app(registry: SchemaRegistry) -> impl App {
// At connect: resolve each registered subject and check the type's schema against it.
let prefetch = SchemaPrefetch::new(registry).check_compatibility(true);
let codec = AvroCodec::registry(&prefetch).register::<Shipment>("shipments-value");
let broker = KafkaBroker::new(["localhost:9092"])
.default_group("shipping-svc")
.schema_prefetch(prefetch);

let replies = codec.clone();
RustStream::new(AppInfo::new("shipping", "0.1.0")).with_broker_codec(broker, codec, |b| {
b.include(ship).out_reply(Publish::default()).codec(replies);
})
}

#[ruststream::app]
fn service() -> impl App {
app(SchemaRegistry::new("http://localhost:8081"))
}