Skip to main content

Slot

Struct Slot 

Source
pub struct Slot<Parent, Child> {
    pub read: fn(&Parent) -> Option<&Child>,
    pub write: fn(Option<&Parent>, Child) -> Parent,
}
Expand description

Where a child’s durable record lives inside its parent’s.

A parent and a child sharing one store would collide on the metadata: each set would overwrite the other’s. A Slot says which part of the parent’s record belongs to the child, so the child’s set becomes a read-modify-write of the parent’s — one record, one write, which is what keeps durable-before-visible meaning what it says. Two writes could be interrupted between them; one cannot.

Both halves are fn pointers rather than closures, for the same reason the composition mappers are: a slot must not capture. It names a fixed place in a type, and a slot that could close over state would be a different place on different calls.

write takes the parent’s record as an Option because the child may write first: nothing is stored until something is, and the child’s own Init is often the first event of the run. The implementation is then “start from the parent’s default, put the child’s part in it”.

#[derive(Clone, Default, PartialEq, Debug)]
struct Parent { mine: u64, childs: Option<u32> }

const CHILD: Slot<Parent, u32> = Slot {
    read: |p| p.childs.as_ref(),
    write: |p, c| Parent { childs: Some(c), ..p.cloned().unwrap_or_default() },
};

assert_eq!((CHILD.read)(&Parent { mine: 1, childs: Some(7) }), Some(&7));
assert_eq!((CHILD.write)(None, 7), Parent { mine: 0, childs: Some(7) });

§The sequence half is SeqSlot

A Slot scopes the metadata only, so Cx::with_durable_child_consuming hands the child a store whose Entry is uninhabited: such a child cannot append, and the signature says so rather than a comment. That is still the right default, and most durable children want nothing else.

A child that appends is composed through SeqSlot as well, with Cx::with_durable_child. This paragraph used to say the shape such a thing would take and that nothing needed it — “building it now would be the framework before its second consumer”. The second consumer arrived: the fail-recovery total-order broadcast keeps a durable record of its own and composes logged_uniform_reliable_broadcast, which is the one protocol here that appends. What was built is what that paragraph described, unchanged.

Fields§

§read: fn(&Parent) -> Option<&Child>

The child’s record, as it sits inside the parent’s.

§write: fn(Option<&Parent>, Child) -> Parent

The parent’s record with the child’s part replaced.

Trait Implementations§

Source§

impl<Parent, Child> Clone for Slot<Parent, Child>

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<Parent, Child> Copy for Slot<Parent, Child>

Source§

impl<Parent, Child> Debug for Slot<Parent, Child>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Parent, Child> Freeze for Slot<Parent, Child>

§

impl<Parent, Child> RefUnwindSafe for Slot<Parent, Child>

§

impl<Parent, Child> Send for Slot<Parent, Child>

§

impl<Parent, Child> Sync for Slot<Parent, Child>

§

impl<Parent, Child> Unpin for Slot<Parent, Child>

§

impl<Parent, Child> UnsafeUnpin for Slot<Parent, Child>

§

impl<Parent, Child> UnwindSafe for Slot<Parent, Child>

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
§

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

§

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<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.

§

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

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

§

fn vzip(self) -> V