pub struct FeedScript { /* private fields */ }Expand description
Scripting and observation handle for a ScriptedFeed.
Every scripting call wakes the reader, so a source parked on the feed picks the change up at once.
Implementations§
Source§impl FeedScript
impl FeedScript
Sourcepub fn deliver(&self, unit: Unit) -> Receipt
pub fn deliver(&self, unit: Unit) -> Receipt
Queue a delivery of unit for the next receive, and return its
receipt. Delivering a unit whose id this method delivered before is a
duplicate. Delivery::deliveries counts the deliveries this method
scripted for an id and their redeliveries together; a unit published
through the feed keeps its own count, whatever its id.
Sourcepub fn dead_letter(&self, receipt: Receipt)
pub fn dead_letter(&self, receipt: Receipt)
Sourcepub fn refuse_next_publish(&self, kind: FeedErrorKind)
pub fn refuse_next_publish(&self, kind: FeedErrorKind)
Refuse the next unscripted publish with kind (repeat to script a
sequence). A refused unit is never delivered.
Sourcepub fn refuse_next_receive(&self, kind: FeedErrorKind)
pub fn refuse_next_receive(&self, kind: FeedErrorKind)
Answer the next receive with kind (repeat to script a sequence).
The call changes nothing in the feed: it takes no delivery, so
held and delivered are as before
it, and it sends no signal. Every kind but Gone is accepted,
including ones the trait does not list for receive, to reach a
reader’s arm for them.
§Panics
If kind is Gone, which has no meaning for
receive.
Sourcepub fn refuse_next_renew(&self, kind: FeedErrorKind)
pub fn refuse_next_renew(&self, kind: FeedErrorKind)
Answer the next renew with kind (repeat to script a sequence).
The call changes nothing in the feed: held and
renewed are as before it. The answer goes to the
next renew whatever its receipt, a lapsed one included. Every kind
but Gone is accepted, including ones the trait does not list for
renew, to reach a reader’s arm for them.
§Panics
If kind is Gone: the feed answers Gone
itself for a receipt it does not hold, and
redeliver or dead_letter
lapses one.
Sourcepub fn refuse_next_acknowledge(&self, kind: FeedErrorKind)
pub fn refuse_next_acknowledge(&self, kind: FeedErrorKind)
Answer the next acknowledge with kind (repeat to script a
sequence).
The call changes nothing in the feed: held and
acknowledged are as before it, so the
delivery stays held for the reader to acknowledge again. The answer
goes to the next acknowledge whatever its receipt. Every kind but
Gone is accepted, including ones the trait does not list for
acknowledge, to reach a reader’s arm for them.
§Panics
If kind is Gone: the feed answers Gone
itself for a receipt it does not hold, and
redeliver or dead_letter
lapses one.
§Examples
use spate_core::feed::{Feed, FeedErrorKind, Unit};
let (feed, script) = spate_test::scripted_feed();
let receipt = script.deliver(Unit::new("day-1", b"2026-10-01".to_vec()));
feed.receive(8).unwrap();
script.refuse_next_acknowledge(FeedErrorKind::Retryable);
let refused = feed.acknowledge(receipt).unwrap_err();
assert_eq!(refused.kind, FeedErrorKind::Retryable);
assert_eq!(script.held(), vec![receipt]);
assert_eq!(script.refusals_left(), 0);
feed.acknowledge(receipt).unwrap();
assert_eq!(script.acknowledged(), vec![receipt]);Sourcepub fn refuse_next_fail(&self, kind: FeedErrorKind)
pub fn refuse_next_fail(&self, kind: FeedErrorKind)
Answer the next fail with kind (repeat to script a sequence).
The call changes nothing in the feed: held and
failed are as before it, so the delivery stays held
for the reader to fail again. The answer goes to the next fail
whatever its receipt. Every kind but Gone is accepted, including
ones the trait does not list for fail, to reach a reader’s arm for
them.
§Panics
If kind is Gone: the feed answers Gone
itself for a receipt it does not hold, and
redeliver or dead_letter
lapses one.
Sourcepub fn refusals_left(&self) -> usize
pub fn refusals_left(&self) -> usize
How many scripted refusals of publish, receive, renew,
acknowledge and fail are not yet served.
Sourcepub fn hold_publishes(&self)
pub fn hold_publishes(&self)
Leave every later publish unsettled until
confirm_held_publishes.
Sourcepub fn confirm_held_publishes(&self)
pub fn confirm_held_publishes(&self)
Confirm every held publish, queue a delivery of each unit in publish order, and stop holding publishes.
Sourcepub fn answer_depth(&self, of: DepthOf, answer: Result<Depth, FeedError>)
pub fn answer_depth(&self, of: DepthOf, answer: Result<Depth, FeedError>)
Answer the next unscripted depth read of of with answer, ahead
of the depth the feed’s own state gives (repeat to script a
sequence). A read with no scripted answer left reports the units
queued as visible and the units held as in flight, or, for
DeadLetters, the units
dead_letter moved as visible, all exact.
A running pipeline makes dead-letter reads of its own, at
startup and then every
dead_letter_read_interval.
A test that scripts or counts the source’s dead-letter reads sets that
option to None.
§Examples
use spate_core::feed::{Depth, DepthOf, Feed, FeedError, FeedErrorKind, Unit};
let (feed, script) = spate_test::scripted_feed();
let mut peer_held = Depth::new("the scripted feed", true);
peer_held.in_flight = 1;
script.answer_depth(DepthOf::Feed, Ok(peer_held.clone()));
script.answer_depth(
DepthOf::Feed,
Err(FeedError::new(FeedErrorKind::Retryable, "throttled")),
);
let read = |of| feed.read_depth(of).unwrap().try_outcome().unwrap();
assert_eq!(read(DepthOf::Feed).unwrap(), peer_held);
assert_eq!(read(DepthOf::Feed).unwrap_err().kind, FeedErrorKind::Retryable);
// With the script spent, the feed reports its own state.
let receipt = script.deliver(Unit::new("a", b"a".to_vec()));
script.dead_letter(receipt);
assert!(read(DepthOf::Feed).unwrap().is_empty());
assert_eq!(read(DepthOf::DeadLetters).unwrap().visible, 1);
assert_eq!(script.depth_reads(DepthOf::Feed), 3);Sourcepub fn hand_back_on_stop(&self)
pub fn hand_back_on_stop(&self)
Make the feed answer hands_back with true, as a
backend does whose stopping reader reads to the stop reserve and hands
back the rest. A scripted feed answers false until this is called.
§Examples
use spate_core::feed::{Feed, Unit};
use std::time::Duration;
let (feed, script) = spate_test::scripted_feed();
assert!(!feed.hands_back());
script.hand_back_on_stop();
assert!(feed.hands_back());
let receipt = script.deliver(Unit::new("day-1", b"2026-10-01".to_vec()));
feed.receive(8).unwrap();
feed.stop_receiving();
feed.hand_back(receipt).unwrap();
feed.close(Duration::from_secs(1));
assert_eq!(script.stopped_receiving(), 1);
assert_eq!(script.handed_back(), vec![receipt]);
assert!(script.held().is_empty());
assert_eq!(script.closes(), vec![Duration::from_secs(1)]);Sourcepub fn stopped_receiving(&self) -> usize
pub fn stopped_receiving(&self) -> usize
How many times the feed was told to stop_receiving.
The feed keeps answering receive after it, so a test sees whether
the reader stopped asking.
Sourcepub fn handed_back(&self) -> Vec<Receipt>
pub fn handed_back(&self) -> Vec<Receipt>
Every receipt handed back, in order. A handed-back delivery is no longer held.
Sourcepub fn depth_reads(&self, of: DepthOf) -> usize
pub fn depth_reads(&self, of: DepthOf) -> usize
How many depth reads of of the feed has answered.
Sourcepub fn held(&self) -> Vec<Receipt>
pub fn held(&self) -> Vec<Receipt>
The receipts received and not yet acknowledged, failed or lapsed, in receipt order.
Sourcepub fn acknowledged(&self) -> Vec<Receipt>
pub fn acknowledged(&self) -> Vec<Receipt>
Every receipt acknowledged, in order.
Sourcepub fn failed(&self) -> Vec<(Receipt, String)>
pub fn failed(&self) -> Vec<(Receipt, String)>
Every receipt failed, with its reason, in order.
Sourcepub fn published(&self) -> Vec<Unit>
pub fn published(&self) -> Vec<Unit>
Every unit passed to publish, in order, whatever its outcome.
Sourcepub fn dead_lettered(&self) -> Vec<Unit>
pub fn dead_lettered(&self) -> Vec<Unit>
Every unit moved to the dead-letter destination by
dead_letter, in order.