Skip to main content

FeedScript

Struct FeedScript 

Source
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

Source

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.

Source

pub fn redeliver(&self, receipt: Receipt) -> Receipt

Deliver the unit receipt names again under a new receipt, as a queue does when a lease lapses. The old receipt lapses: every later call with it returns Gone.

§Panics

If receipt names no delivery that is queued or held.

Source

pub fn dead_letter(&self, receipt: Receipt)

Move the unit receipt names to the dead-letter destination. The receipt lapses as for redeliver.

§Panics

If receipt names no delivery that is queued or held.

Source

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.

Source

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.

Source

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.

Source

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]);
Source

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.

Source

pub fn refusals_left(&self) -> usize

How many scripted refusals of publish, receive, renew, acknowledge and fail are not yet served.

Source

pub fn hold_publishes(&self)

Leave every later publish unsettled until confirm_held_publishes.

Source

pub fn confirm_held_publishes(&self)

Confirm every held publish, queue a delivery of each unit in publish order, and stop holding publishes.

Source

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);
Source

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)]);
Source

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.

Source

pub fn handed_back(&self) -> Vec<Receipt>

Every receipt handed back, in order. A handed-back delivery is no longer held.

Source

pub fn closes(&self) -> Vec<Duration>

The bound of every close, in order. A close settles at once and lets go of nothing, so held still shows what the reader held.

Source

pub fn depth_reads(&self, of: DepthOf) -> usize

How many depth reads of of the feed has answered.

Source

pub fn delivered(&self) -> Vec<Delivery>

Every delivery receive handed out, in order.

Source

pub fn held(&self) -> Vec<Receipt>

The receipts received and not yet acknowledged, failed or lapsed, in receipt order.

Source

pub fn acknowledged(&self) -> Vec<Receipt>

Every receipt acknowledged, in order.

Source

pub fn failed(&self) -> Vec<(Receipt, String)>

Every receipt failed, with its reason, in order.

Source

pub fn renewed(&self) -> Vec<Receipt>

Every receipt renewed, in order, one entry per call.

Source

pub fn gone(&self) -> Vec<Receipt>

Every receipt a call was answered Gone for, in order.

Source

pub fn published(&self) -> Vec<Unit>

Every unit passed to publish, in order, whatever its outcome.

Source

pub fn dead_lettered(&self) -> Vec<Unit>

Every unit moved to the dead-letter destination by dead_letter, in order.

Trait Implementations§

Source§

impl Clone for FeedScript

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FeedScript

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more