Struct Context

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

Context contains Node state and references to the runtime.

Implementations§

Source§

impl Context

Source

pub fn runtime(&self) -> &Handle

Return runtime clone

Source

pub fn primary_address(&self) -> &Address

Return the primary address of the current worker

Source

pub fn additional_addresses(&self) -> impl Iterator<Item = &Address>

Return additional addresses of the current worker

Source

pub fn mailboxes(&self) -> &Mailboxes

Return a reference to the mailboxes of this context

Source

pub fn flow_controls(&self) -> &FlowControls

Shared FlowControls instance

Source

pub fn tracing_context(&self) -> OpenTelemetryContext

Return the tracing context

Source

pub fn set_tracing_context(&mut self, tracing_context: OpenTelemetryContext)

Set the current tracing context

Source§

impl Context

Source

pub fn list_workers(&self) -> Result<Vec<Address>, Error>

Return a list of all available worker addresses on a node

Source

pub fn is_worker_registered_at(&self, address: &Address) -> Result<bool, Error>

Return true if a worker is already registered at this address

Source

pub fn find_terminal_address<'a>( &self, addresses: impl Iterator<Item = &'a Address>, ) -> Result<Option<(&'a Address, AddressMetadata)>, Error>

Finds the terminal address of a route, if present

Source

pub fn get_metadata( &self, address: &Address, ) -> Result<Option<AddressMetadata>, Error>

Read metadata for the provided address

Source§

impl Context

Source

pub fn new_detached_with_mailboxes( &self, mailboxes: Mailboxes, ) -> Result<Context, Error>

TODO basically we can just rename Self::new_detached_impl()

Source

pub fn new_detached( &self, address: impl Into<Address>, incoming: impl IncomingAccessControl, outgoing: impl OutgoingAccessControl, ) -> Result<Context, Error>

Create a new detached Context without spawning a full worker

Note: this function is very low-level. For most users start_worker() is the recommended way to create a new worker context.

Approximate flow of starting a detached address:

  1. Create and Spawn AsyncDrop::run
  2. StartWorker message -> Router
  3. First address is considered a primary_addr (main_addr)
  4. Check if router.map.address_records_map already has primary_addr
  5. AddressRecord is created and inserted in router.map
  6. Iterate over metadata: Check if it belongs to that record Set is_terminal true in router.map.address_metadata_map (if address is terminal) Insert attributes one by one
  7. For each address we insert pair (Address, primary_addr) into router.map.alias_map, including (primary_addr, primary_addr itself)

Approximate flow of stopping a detached address:

  1. Context::Drop is called when Context is dropped by rust runtime (according to RAII principle)
  2. async_drop_sender is used to send the Context address
  3. AsyncDrop sends StopWorker message -> Router
  4. Get AddressRecord
  5. router.map.free_address(main_address) is called (given Router state is running): remote main_address from router.map.stopping (it’s not their anyway, unless in was a cluster and node was shutting down) Remove AddressRecord from router.map.address_records_map (return error if not found) Remove all alias in router.map.alias_map Remote all meta from router.map.address_metadata
Source§

impl Context

Source

pub async fn receive<M>(&mut self) -> Result<Routed<M>, Error>
where M: Message,

Block the current worker to wait for a typed message

This function may return a Err(FailedLoadData) if the underlying worker was shut down, or Err(Timeout) if the call was waiting for longer than the default timeout.

Use receive_extended() to use a specific timeout period.

Will return None if the corresponding worker has been stopped, or the underlying Node has shut down.

Source

pub async fn receive_extended<M>( &mut self, options: MessageReceiveOptions, ) -> Result<Routed<M>, Error>
where M: Message,

Wait to receive a typed message

Source§

impl Context

Source

pub fn register<A>(&self, type_: TransportType, addr: A) -> Result<(), Error>
where A: Into<Address>,

Register a router for a specific address type

Source§

impl Context

Source

pub async fn send_and_receive<T, R>( &self, route: impl Into<Route>, msg: T, ) -> Result<R, Error>
where T: Message, R: Message,

Using a temporary new context, send a message and then receive a message with default timeout and no flow control

This helper function uses new_detached, send, and receive internally. See their documentation for more details.

Source

pub async fn send_and_receive_extended<T, R>( &self, route: impl Into<Route>, msg: T, options: MessageSendReceiveOptions, ) -> Result<Routed<R>, Error>
where T: Message, R: Message,

Using a temporary new context, send a message and then receive a message

This helper function uses new_detached, send, and receive internally. See their documentation for more details.

Source

pub async fn send_to_self<A, M>( &self, from: A, addr: A, msg: M, ) -> Result<(), Error>
where A: Into<Address>, M: Message + Send + 'static,

Send a message to another address associated with this worker

This function is a simple wrapper around Self::send() which validates the address given to it and will reject invalid addresses.

Source

pub async fn send<R, M>(&self, route: R, msg: M) -> Result<(), Error>
where R: Into<Route>, M: Message,

Send a message to an address or via a fully-qualified route

Routes can be constructed from a set of Addresses, or via the RouteBuilder type. Routes can contain middleware router addresses, which will re-address messages that need to be handled by specific domain workers.

use ockam_core::{deserialize, serialize, Decodable, Encodable, Encoded};

async fn test(ctx: &mut Context) -> Result<()> {
use ockam_core::Message;
use serde::{Serialize, Deserialize};

#[derive(Message, Serialize, Deserialize)]
struct MyMessage(String);

impl MyMessage {
    fn new(s: &str) -> Self {
        Self(s.into())
    }
}

impl Encodable for MyMessage {
    fn encode(self) -> Result<Encoded> {
        Ok(serialize(self)?)
    }
}

impl Decodable for MyMessage {
    fn decode(e: &[u8]) -> Result<Self> {
        Ok(deserialize(e)?)
    }
}

ctx.send("my-test-worker", MyMessage::new("Hello you there :)")).await?;
Ok(())
Source

pub async fn send_with_local_info<R, M>( &self, route: R, msg: M, local_info: Vec<LocalInfo>, ) -> Result<(), Error>
where R: Into<Route>, M: Message,

Send a message to an address or via a fully-qualified route after attaching the given LocalInfo to the message.

Source

pub async fn send_from_address<R, M>( &self, route: R, msg: M, sending_address: Address, ) -> Result<(), Error>
where R: Into<Route>, M: Message,

Send a message to an address or via a fully-qualified route

Routes can be constructed from a set of Addresses, or via the RouteBuilder type. Routes can contain middleware router addresses, which will re-address messages that need to be handled by specific domain workers.

This function additionally takes the sending address parameter, to specify which of a worker’s (or processor’s) addresses should be used.

Source

pub async fn forward(&self, local_msg: LocalMessage) -> Result<(), Error>

Forward a transport message to its next routing destination

Similar to Context::send, but taking a LocalMessage, which contains the full destination route, and calculated return route for this hop.

Note: you most likely want to use Context::send instead, unless you are writing an external router implementation for ockam node.

Source

pub async fn forward_from_address( &self, local_msg: LocalMessage, sending_address: Address, ) -> Result<(), Error>

Forward a transport message to its next routing destination

Similar to Context::send, but taking a LocalMessage, which contains the full destination route, and calculated return route for this hop.

Note: you most likely want to use Context::send instead, unless you are writing an external router implementation for ockam node.

Source§

impl Context

Source

pub async fn shutdown_node(&self) -> Result<(), Error>

Signal to the local runtime to shut down

This call will hang until a safe shutdown has been completed. The default timeout for a safe shutdown is 1 second. You can change this behaviour by calling Context::shutdown_node_with_timeout directly.

Source

pub async fn shutdown_node_with_timeout(&self, seconds: u8) -> Result<(), Error>

Signal to the local runtime to shut down

This call will hang until a safe shutdown has been completed or the desired timeout has been reached.

Source§

impl Context

Source

pub fn register_transport(&self, transport: Arc<dyn Transport>)

Return the list of supported transports

Source

pub fn get_transport( &self, transport_type: TransportType, ) -> Option<Arc<dyn Transport>>

Return a transport by type

Source

pub fn is_transport_registered(&self, transport_type: TransportType) -> bool

Return true if a given transport has already been registered

Source

pub async fn resolve_transport_route( &self, route: Route, ) -> Result<Route, Error>

For each address handled by a given transport in a route, for example, (TCP, “127.0.0.1:4000”) Create a worker supporting the routing of messages for this transport and replace the address in the route with the worker address

Source

pub async fn resolve_transport_route_static( route: Route, transports: HashMap<TransportType, Arc<dyn Transport>>, ) -> Result<(Route, Option<Address>), Error>

For each address handled by a given transport in a route, for example, (TCP, “127.0.0.1:4000”) Create a worker supporting the routing of messages for this transport and replace the address in the route with the worker address. Also, returns the connection worker address, if that connection was instantiated in this function.

Source§

impl Context

Source

pub fn start_worker<W>( &self, address: impl Into<Address>, worker: W, ) -> Result<(), Error>
where W: Worker<Context = Context>,

Start a new worker instance at the given address. Default AccessControl is AllowAll

A worker is an asynchronous piece of code that can send and receive messages of a specific type. This type is encoded via the Worker trait. If your code relies on a manual run-loop you may want to use start_processor() instead!

Each address in the set must be unique and unused on the current node. Workers must implement the Worker trait and be thread-safe. Workers run asynchronously and will be scheduled independently of each other. To wait for the initialisation of your worker to complete you can use wait_for().

use ockam_core::{Result, Worker, worker};
use ockam_node::Context;

struct MyWorker;

#[worker]
impl Worker for MyWorker {
    type Context = Context;
    type Message = String;
}

fn start_my_worker(ctx: &mut Context) -> Result<()> {
    ctx.start_worker("my-worker-address", MyWorker)
}

Approximate flow of starting a worker:

  1. StartWorker message -> Router
  2. First address is considered a primary_addr (main_addr)
  3. Check if router.map.address_records_map already has primary_addr
  4. AddressRecord is created and inserted in router.map
  5. Iterate over metadata: Check if it belongs to that record Set is_terminal true in router.map.address_metadata_map (if address is terminal) Insert attributes one by one
  6. For each address we insert pair (Address, primary_addr) into router.map.alias_map, including (primary_addr, primary_addr itself)
  7. WorkerRelay is spawned as a tokio task: WorkerRelay calls initialize WorkerRelay calls Worker::handle_message for each message until either stop signal is received (CtrlSignal::InterruptStop to AddressRecord::ctrl_tx) there are no messages coming to that receiver (the sender side is dropped)
Source

pub fn start_worker_with_access_control<W>( &self, address: impl Into<Address>, worker: W, incoming: impl IncomingAccessControl, outgoing: impl OutgoingAccessControl, ) -> Result<(), Error>
where W: Worker<Context = Context>,

Start a new worker instance at the given address

A worker is an asynchronous piece of code that can send and receive messages of a specific type. This type is encoded via the Worker trait. If your code relies on a manual run-loop you may want to use start_processor() instead!

Each address in the set must be unique and unused on the current node. Workers must implement the Worker trait and be thread-safe. Workers run asynchronously and will be scheduled independently of each other.

use ockam_core::{AllowAll, Result, Worker, worker};
use ockam_node::Context;

struct MyWorker;

#[worker]
impl Worker for MyWorker {
    type Context = Context;
    type Message = String;
}

 fn start_my_worker(ctx: &mut Context) -> Result<()> {
    ctx.start_worker_with_access_control("my-worker-address", MyWorker, AllowAll, AllowAll)
}
Source

pub fn start_processor<P>( &self, address: impl Into<Address>, processor: P, ) -> Result<(), Error>
where P: Processor<Context = Context>,

Start a new processor instance at the given address. Default AccessControl is DenyAll

A processor is an asynchronous piece of code that runs a custom run loop, with access to a worker context to send and receive messages. If your code is built around responding to message events, consider using start_worker() instead!

Approximate flow of starting a processor:

  1. StartProcessor message -> Router
  2. First address is considered a primary_addr (main_addr)
  3. Check if router.map.address_records_map already has primary_addr
  4. AddressRecord is created and inserted in router.map
  5. Iterate over metadata: Check if it belongs to that record Set is_terminal true in router.map.address_metadata_map (if address is terminal) Insert attributes one by one
  6. For each address we insert pair (Address, primary_addr) into router.map.alias_map, including (primary_addr, primary_addr itself)
  7. ProcessorRelay is spawned as a tokio task: ProcessorRelay calls Processor::initialize ProcessorRelay calls Processor::process until either false is returned or stop signal is received (CtrlSignal::InterruptStop to AddressRecord::ctrl_tx)
Source

pub fn start_processor_with_access_control<P>( &self, address: impl Into<Address>, processor: P, incoming: impl IncomingAccessControl, outgoing: impl OutgoingAccessControl, ) -> Result<(), Error>
where P: Processor<Context = Context>,

Start a new processor instance at the given address

A processor is an asynchronous piece of code that runs a custom run loop, with access to a worker context to send and receive messages. If your code is built around responding to message events, consider using start_worker() instead!

Source

pub fn stop_address(&self, address: &Address) -> Result<(), Error>

Stop a Worker or a Processor running on given Address

Source

pub fn stop_primary_address(&self) -> Result<(), Error>

Stop a Worker or a Processor running on the context primary address

Trait Implementations§

Source§

impl Debug for Context

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Drop for Context

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl TryClone for Context

Source§

fn try_clone(&self) -> Result<Context, Error>

Try cloning an object and return an Err in case of failure.

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

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
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,