Struct Runtime

Source
pub struct Runtime { /* private fields */ }
Expand description

The core of the distributed task management system.

Fundamentally, the Runtime is responsible for managing the channels that Tasks and Directives use to communicate, and provides a simple interface for interacting with these channels.

This runtime should be used in an orchestration context, where a single node is responsible for managing the execution of tasks. This is in contrast to the WorkerRuntime, which is used by worker nodes that execute tasks.

The primary purpose of this runtime is to facilitate the instantiation of new coordination channels for dispatching Tasks and receiving their associated TaskResults. It takes care of namespacing new result channels such that users can consume them in an isolated manner. Directives will use this to create a siloed channel upon which they can listen to only the results of the Tasks they manage. It also takes care of synchronizing disparate sender and receiver channels such that closing the sender terminates the receiver.

§Emulation

The main Runtime provides emulation functionality for the worker. This can be enabled by passing the config::Runtime::InMemory field as part of the configuration to Runtime::from_config. This will spin up a multi-threaded worker emulator that will execute multiple WorkerRuntimes concurrently. This can be used to simulate a distributed environment in-memory, and finds immediate practical use in writing tests.

See the runtime module documentation for more information on runtime semantics.

Implementations§

Source§

impl Runtime

Source

pub async fn from_config(config: &Config, marker: Marker) -> Result<Self>

Initializes the Runtime with the provided Config.

Source

pub async fn in_memory() -> Result<Self>

Short-hand for initializing an in-memory Runtime.

Source

pub async fn close(&self) -> Result<()>

Source

pub async fn lease_coordinated_task_channel<'a, Op: Operation + 'a, Metadata: Serializable + 'a>( &self, ) -> Result<(String, Box<dyn Publisher<Task<'a, Op, Metadata>> + Send + Unpin + Sync + 'a>, LeaseGuard<DynamicChannel, Box<dyn Stream<Item = (TaskResult<Op, Metadata>, Box<dyn Acker>)> + Send + Unpin + 'a>>)>

Leases a new discrete coordinated channel for asynchronously dispatching Tasks and receiving their TaskResults.

§Design notes
  • The returned receiver is wrapped in a LeaseGuard that will release the leased Channel once dropped.
  • A unique identifier is returned for the newly leased Channel that is bound to the receiver. This can be used to route TaskResults back to that channel such that they’re propagated to provided receiver.
  • Even though the sender and receiver interact with two distinct channels, they are bound by coordinated_channel, which ensures that open/closed state and pending message state are synchronized between them.
  • The provided receiver automatically deserializes AnyTaskResults into typed TaskResults on behalf of the caller.

Users should take care to close the sender once all tasks have been dispatched. This will ensure that the receiver is terminated once all results have been received. Without this, the receiver will block indefinitely. Alternatively, returning early without closing the sender will will be fine too, as the sender will be closed once dropped.

§Example
use paladin::{
    RemoteExecute,
    runtime::Runtime,
    task::Task,
    operation::{Operation, Result},
};
use serde::{Deserialize, Serialize};
use futures::StreamExt;

#[derive(Serialize, Deserialize)]
struct Metadata {
    id: usize,
}

async fn run_task<Op: Operation>(op: &Op, runtime: &Runtime, input: Op::Input) -> anyhow::Result<()> {
    let (identifier, mut sender, mut receiver) = runtime.lease_coordinated_task_channel::<Op, Metadata>().await?;

    // Issue a task with the identifier of the receiver
    sender.publish(&Task {
        routing_key: identifier,
        metadata: Metadata { id: 0 },
        op,
        input,
    })
    .await?;
    sender.close().await?;


    while let Some((result, acker)) = receiver.next().await {
            // ... handle result
    }

    Ok(())
}
§Metadata

Metadata is a generic parameter that implements Serializable, used to encode additional information into a Task that is relevant to the particular Directive orchestrating it. This can be useful in cases where a Directive needs to coordinate the results of multiple Tasks.

Trait Implementations§

Source§

impl Drop for Runtime

Drop the worker emulator when the runtime is dropped.

Source§

fn drop(&mut self)

Executes the destructor for this type. 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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
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.
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
Source§

impl<T> ErasedDestructor for T
where T: 'static,