PullSubscriber class
A zenoh pull subscriber: samples accumulate in a bounded channel and the caller takes them out on demand.
Unlike Subscriber, which pushes samples into a stream as they arrive, a PullSubscriber buffers them and hands them over one at a time when tryRecv is called — so the consumer sets the pace.
The kind chosen at declaration decides what happens when the buffer fills: ChannelKind.ring drops the oldest sample and never blocks the publisher, ChannelKind.fifo keeps every sample and blocks the publisher instead. The kinds also differ at the END of a channel's life: when the producer dies, a fifo drains what it still holds before reporting disconnected, while a ring discards it. Both behaviours are canon's own, measured at 1.8.0, and rendered here unsmoothed.
Drain only if the residue matters. close releases the channel with whatever it still holds — our handle owns both halves, so there is no post-close drain window. Poll to exhaustion first if you need those samples.
⚠️ This used to read "drain before you close", and it silently carried a CORRECTNESS claim it could not honour. Closing an undrained, overflowing fifo once hung the calling isolate permanently. That is fixed at the source — close now releases the receiving end before undeclaring — and draining could never have prevented it from one isolate anyway: measured at canon level, the hang persisted even after the producer was gone. Draining is residue guidance, and nothing more.
⚠️ One teardown ORDER still matters, and it is canon's, not this
binding's: close pull handles before closing their session when a fifo
may be in overflow. A session closed first still stalls — measured, and
pinned as a residual in test/fifo_close_deadlock_test.dart. This unit
does not fix that path.
Call close when done to undeclare the subscriber and release native resources.
This object holds a native handle, so it cannot cross an isolate
boundary: a copy would share this one's native address while carrying
its own fresh disposal flag, and the second release would be a
use-after-free. Sending it throws ArgumentError naming the class.
⛔ No NativeFinalizer is attached to this class, deliberately: its
close() is seven steps of which four are Dart-side — completing a pending
waiter, releasing the demand gate, closing a ReceivePort — and a finalizer
callback has no isolate to run them in. It is also never collected in
practice, so a finalizer there would be dead code.
Releasing it explicitly is therefore the only thing that reclaims it.
- Implemented types
Constructors
-
PullSubscriber(Pointer<
Uint8> _subscriberHandle, Pointer<Uint8> _handlerHandle, Pointer<Uint8> _teeHandle, ReceivePort _receivePort, String _keyExpr, ChannelKind _kind, [bool _retainPayload = false]) -
Internal constructor. Use
Session.declarePullSubscriberinstead.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- keyExpr → String
-
The key expression this pull subscriber is declared on.
no setter
- kind → ChannelKind
-
The bounded channel kind backing this subscriber.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
stream
→ Stream<
Sample> -
A bounded, demand-gated Stream view over this handle's own recv.
no setter
Methods
-
close(
) → void - Closes the pull subscriber and releases native resources.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
recv(
) → Future< RecvResult< Sample> > - Waits for the next sample.
-
toString(
) → String -
A string representation of this object.
inherited
-
tryRecv(
) → RecvResult< Sample> - Tries to receive a sample, without waiting.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited