v0.5.0 · Interface

handler

Receiving records that a provider pushed, rather than reading a stream.

The counterpart to consumer: there, a workload holds a consumer resource and pulls from records(), which obliges it to be long-lived — something has to own the stream and keep the group heartbeat alive between reads. Exporting handler inverts that. The provider does the holding, and calls a workload only when there is a batch for it, so the workload can be an ordinary per-request component that does not exist between batches.

That shape is what a bursty topic wants: instances start when there is work and retire when the burst drains, rather than one long-lived consumer holding a stream between bursts.

How wide that goes is the partition count, not the record count. A provider reads each partition independently and calls a workload with a batch from one of them, so a hundred records spread over ten partitions can occupy ten instances at once, while a hundred on a single partition are one call after another — the same ordering rule Kafka gives every consumer. Size partitions for the concurrency you want; replicas and pools divide that up, they do not multiply it.

This is possible from a host component plugin

It was not always. A component plugin's imports resolve against the host's own plugins, never against workloads, so for a while a plugin genuinely had no way to invoke an export on a workload and delivery had to be initiated from the workload side. wasmcloud:host/workload-call removed that restriction: a plugin opens a target for a workload id and an interface, and calls it. A plugin that pushes imports this interface and holds such a target; the workload exports it.

Delivery semantics

  • At least once. Offsets move only after handle returns ok. An error, a stopped workload, or a provider restart mid-batch all leave them where they were and the records are redelivered, so an idempotent handler is a requirement rather than a nicety.
  • One partition per call. Every record in a batch comes from the same partition, in offset order. Kafka orders within a partition and commits one offset per partition, so partitions are exactly the pieces that can be handled — and committed — independently. A provider is free to dispatch different partitions concurrently, and that is where the parallelism comes from: more of it means more partitions, the same answer Kafka gives every other consumer.
  • An error means "not handled". transient asks for redelivery; permanent says redelivery is pointless and the batch should be dead-lettered now, because holding a partition hostage to one bad batch stops every record behind it. A provider that only counts attempts has to wait out the retries to reach the same conclusion.