pub struct Process<M, S = Bincode> { /* private fields */ }
Expand description

Processes are isolated units of compute.

In lunatic, all code runs inside processes. Processes run concurrently and communicate via message passing.

Lunatic’s processes should not be confused with operating system processes. Processes in lunatic are extremely lightweight in terms of memory and CPU (even compared to threads as used in many other programming languages). Because of this, it is not uncommon to have tens or even hundreds of thousands of processes running simultaneously.

The Process type allows us to spawn new processes from rust functions. There are two kinds of processes:

  1. Mailbox based processes
  2. Protocol based processes

They are differentiated by the second argument of the entry function.

Mailbox based processes

A mailbox process takes a Mailbox that can only receive messages of one type.

Example

let child = Process::spawn(1, |capture, mailbox: Mailbox<i32>| {
   assert_eq!(capture, 1);
   assert_eq!(mailbox.receive(), 2);
});

child.send(2);

Processes don’t share any memory and messages sent between them need to be serialized. By default, the Bincode serializer is used, but other serializers that implement the Serializer trait can be used instead. The serializer just needs to be added to the Mailbox type (e.g. Mailbox<i32, MessagePack>).

Processes can also be linked together using the spawn_link function. This means that if one of them fails (panics) the other will be killed too. It is always recommended to spawn linked processes when they depend on each other. That way we can avoid one process forever waiting on a message from another process that doesn’t exist anymore.

Protocol based processes

A protocol process takes a Protocol that can define a sequence of messages that will be exchanged between two processes. This is also known as a session type. The child will get a reference to the protocol and the parent will get a reference to the opposite protocol.

Example

type AddProtocol = Recv<i32, Recv<i32, Send<i32, End>>>;
let child = Process::spawn(1, |capture: i32, protocol: Protocol<AddProtocol>| {
    assert_eq!(capture, 1);
    let (protocol, a) = protocol.receive();
    let (protocol, b) = protocol.receive();
    let _ = protocol.send(capture + a + b);
});

let child = child.send(2);
let child = child.send(2);
let (_, result) = child.receive();
assert_eq!(result, 5);

The rust type system guarantees that the all messages are sent in the correct order and are of correct type. Code that doesn’t follow the protocol would not compile.

Same as the mailbox, the protocol based process can choose another serializer (e.g. Protocol<AddProtocol, MessagePack>).

If a protocol based process is dropped before the End state is reached, the drop will panic.

Implementations

Spawn a process.

Spawn a process on a remote node.

Spawn a process on a remote node.

Spawn a linked process.

Spawn a linked process with a tag.

Allows the caller to provide a tag for the link.

Spawn a process with a custom configuration.

Spawn a linked process with a custom configuration.

Spawn a linked process with a custom configuration & provide tag for linking.

Returns a local node process ID.

Returns a node ID.

Link process to the one currently running.

Unlink processes from the caller.

Kill this process

Register process under a name.

Look up a process.

Send a message to the process.

Panics

This function will panic if the received message can’t be serialized into M with serializer S.

Send a message to the process after the specified duration has passed.

Panics

This function will panic if the received message can’t be serialized into M with serializer S.

Send message to process with a specific tag.

Panics

This function will panic if the received message can’t be serialized into M with serializer S.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Deserialize this value from the given Serde deserializer. Read more

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

Processes are equal if their process id and node id are equal.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Serialize this value into the given Serde serializer. Read more

Proccess equality comparison is an equivalance relation

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.

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

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.