Nodes and Workers
Ockam Nodes and Workers decouple applications from the host environment and enable simple interfaces for stateful, asynchronous, and bi-directional message-based protocols.
At Ockam's core is a collection of cryptographic and messaging protocols. These protocols enable private and secure by design applications that provide end-to-end application layer trust in data.
Ockam is designed to make these protocols easy and safe to use in any application environment – from highly scalable cloud services to tiny battery operated microcontroller based devices.
Many included protocols require multiple steps and have complicated internal state that must be managed with care. Protocol steps can often be initiated by any participant so it can be quite challenging to make these protocols simple to use, secure, and platform independent.
Ockam Nodes, Workers, and Services help hide this complexity to provide simple interfaces for stateful and asynchronous message-based protocols.
Nodes
An Ockam Node is any program that can interact with other Ockam Nodes using various Ockam protocols like Ockam Routing and Ockam Secure Channels.
A typical Ockam Node is implemented as an asynchronous execution environment that can run very lightweight, concurrent, stateful actors called Ockam Workers. Using Ockam Routing, a node can deliver messages from one worker to another local worker. Using Ockam Transports, nodes can also route messages to workers on other remote nodes.
In the following code snippet we create a node in Rust and then immediately stop it:
A node requires an asynchronous runtime to concurrently execute workers. The default Ockam Node implementation in Rust uses tokio
, a popular asynchronous runtime in the Rust ecosystem. There are also Ockam Node implementations that support various no_std
embedded targets.
Nodes can be implemented in any language. The only requirement is that understand various Ockam protocols like Routing, Secure Channels, Identities etc.
Workers
Ockam Nodes run very lightweight, concurrent, and stateful actors called Ockam Workers. They are like processes on your operating system, except that they all live inside one node and are very lightweight so a node can have hundreds of thousands of them, depending on the capabilities of the machine hosting the node.
When a worker is started on a node, it is given one or more addresses. The node maintains a mailbox for each address and whenever a message arrives for a specific address it delivers that message to the corresponding worker. In response to a message, a worker can: make local decisions, change internal state, create more workers, or send more messages.
Echoer worker
To create a worker, we create a struct that can optionally have some fields to store the worker's internal state. If the worker is stateless, it can be defined as a field-less unit struct.
This struct:
Must implement the
ockam::Worker
trait.Must have the
#[ockam::worker]
attribute on the Worker trait implementation.Must define two associated types
Context
andMessage
The
Context
type is set toockam::Context.
The
Message
type must be set to the type of messages the worker wishes to handle.
App worker
When a new node starts and calls an async
main function, it turns that function into a worker with address of "app"
. This makes it easy to send and receive messages from the main function (i.e the "app"
worker).
In the code below, we start a new Echoer
worker at address "echoer"
, send this "echoer"
a message "Hello Ockam!"
and then wait to receive a String
reply back from the "echoer"
.
Run the above example:
Message Flow
The message flow looked like this:
Next, let’s explore how Ockam’s Application Layer Routing enables us to create protocols that provide end-to-end guarantees.
Last updated