Module glommio::channels::channel_mesh [−][src]
A mesh-like structure to connect a set of executors
A channel mesh consists of a group of participating executors (peers) and the channels between selected pairs of them. Two kinds of meshes are supported depending on the peer-pair selection criteria: full mesh and partial mesh.
With full mesh, every pair of distinct peers are selected, so messages can be sent to every other peer. Full mesh is useful for building kinds of sharding. With partial mesh, peers are assigned a role of either producer or consumer when they join the mesh, and channels are created from producers to consumers.
Within a mesh, peers are identified by unique peer ids, which are used to specify the source/destination which messages are sent to/received from. Peer ids are determined when the last peer joins the mesh by the indexes to the list of all peers sorted by their executor ids. In this way, multiple meshes can be built over the same set of peers, and the peer ids are guaranteed to be identical across meshes for each peer. This invariance makes it possible to cooperate with multiple meshes.
Examples
Full mesh
use glommio::enclose; use glommio::prelude::*; use glommio::channels::channel_mesh::MeshBuilder; let nr_peers = 5; let channel_size = 100; let mesh_builder = MeshBuilder::full(nr_peers, channel_size); let executors = (0..nr_peers).map(|_| { LocalExecutorBuilder::new().spawn(enclose!((mesh_builder) move || async move { let (sender, receiver) = mesh_builder.join().await.unwrap(); Local::local(async move { for peer in 0..sender.nr_consumers() { if peer != sender.peer_id() { sender.send_to(peer, (sender.peer_id(), peer)).await.unwrap(); } } }).detach(); for peer in 0..receiver.nr_producers() { if peer != receiver.peer_id() { assert_eq!((peer, receiver.peer_id()), receiver.recv_from(peer).await.unwrap().unwrap()); } } })) }); for ex in executors.collect::<Vec<_>>() { ex.unwrap().join().unwrap(); }
Partial mesh
use glommio::enclose; use glommio::prelude::*; use glommio::channels::channel_mesh::{MeshBuilder, Role}; let nr_producers = 2; let nr_consumers = 3; let channel_size = 100; let mesh_builder = MeshBuilder::partial(nr_producers + nr_consumers, channel_size); let producers = (0..nr_producers).map(|i| { LocalExecutorBuilder::new().spawn(enclose!((mesh_builder) move || async move { let (sender, receiver) = mesh_builder.join(Role::Producer).await.unwrap(); assert_eq!(nr_consumers, sender.nr_consumers()); assert_eq!(Some(i), sender.producer_id()); assert_eq!(0, receiver.nr_producers()); assert_eq!(None, receiver.consumer_id()); for consumer_id in 0..sender.nr_consumers() { sender.send_to(consumer_id, (sender.producer_id().unwrap(), consumer_id)).await.unwrap(); } })) }); let consumers = (0..nr_consumers).map(|i| { LocalExecutorBuilder::new().spawn(enclose!((mesh_builder) move || async move { let (sender, receiver) = mesh_builder.join(Role::Consumer).await.unwrap(); assert_eq!(0, sender.nr_consumers()); assert_eq!(None, sender.producer_id()); assert_eq!(nr_producers, receiver.nr_producers()); assert_eq!(Some(i), receiver.consumer_id()); for producer_id in 0..receiver.nr_producers() { assert_eq!((producer_id, receiver.consumer_id().unwrap()), receiver.recv_from(producer_id).await.unwrap().unwrap()); } })) }); for ex in producers.chain(consumers).collect::<Vec<_>>() { ex.unwrap().join().unwrap(); }
Structs
Full | Adapter for full mesh |
MeshBuilder | A builder for channel mesh |
Partial | Adapter for partial mesh |
Receivers | Receiver side |
Senders | Sender side |
Enums
Role | The role an executor plays in the mesh |
Traits
MeshAdapter | An adapter for MeshBuilder |
Type Definitions
FullMesh | Alias for full mesh builder |
PartialMesh | Alias for partial mesh builder |