Skip to main content

RecvChannel

Struct RecvChannel 

Source
pub struct RecvChannel<R> { /* private fields */ }
Expand description

Synchronous, value receiving channel.

This channel type is characterized by the return type of its recv method. No messages can be sent through this channel, but the value generated by running a Join Pattern

Sending a message on this channel will block the current thread until a Join Pattern that this channel is part of has fired.

Implementations§

Source§

impl<R> RecvChannel<R>
where R: Any + Send,

Source

pub fn recv(&self) -> Result<R, RecvError>

Receive value generated by fired Join Pattern.

§Panics

Panics if it was not possible to send a return Sender to the Junction.

Examples found in repository?
examples/storage-cell.rs (line 104)
3fn main() {
4    /* Start of the Join Pattern setup. */
5
6    // Declare a new Junction to create new channels and construct new
7    // Join Patterns based on them.
8    let cell = Junction::new();
9
10    // New channel to retrieve the value of the storage cell.
11    let get = cell.recv_channel::<i32>();
12
13    // New channel to update the value of the storage cell.
14    let put = cell.send_channel::<i32>();
15
16    // New channel to swap the value of the storage cell for a new one and
17    // retrieve the value that was just replaced.
18    let swap = cell.bidir_channel::<i32, i32>();
19
20    // New channel that will actually carry the value so that at no point
21    // any given thread will have possession over it so concurrency issues
22    // are avoided by design.
23    let val = cell.send_channel::<i32>();
24
25    // Set up some clones of the above channels we can move over to the
26    // thread in which the function body of the Join Pattern will run.
27    //
28    // Clones of channels work like clones of the std::sync::mpsc::Sender
29    // clones - any message sent from the clone will be received as if
30    // sent from the original.
31    let get_val = val.clone();
32    let put_val = val.clone();
33    let swap_val = val.clone();
34    let val_val = val.clone();
35
36    // Declare a new Join Pattern to update the storage cell value. If
37    // both the put and val channel have sent a message, meaning someone
38    // requested a value update and there is a value to be updated, send
39    // a new val message through one of val's clones that carries the
40    // updated value.
41    cell.when(&put).and(&val).then_do(move |new, _old| {
42        println!(">> put-val pattern fired with new={}!", new);
43        put_val.send(new).unwrap();
44    });
45
46    // Declare a new Join Pattern to retrieve the storage cell value. If
47    // both the get and val channel have sent a message, meaning someone
48    // requested the value and there is a value to be given, return that
49    // value and resend it through one of val's clones so that the value
50    // is still available in future and not just consumed once.
51    cell.when(&val).and_recv(&get).then_do(move |v| {
52        println!(">> val-get pattern fired with v={}!", v);
53
54        get_val.send(v.clone()).unwrap();
55
56        v
57    });
58
59    // Declare a new Join Pattern to swap the storage cell value with a
60    // new one and retrieve the old. Essentially works like a combination
61    // of the previous two Join Patterns, with one crucial distinction:
62    // with this Join Pattern, the update of the value and the retrieval
63    // of the old are atomic, meaning that it is guaranteed that even in
64    // a multithreaded environment with many users accessing the storage
65    // cell, the value retrieved is exactly the value that has been
66    // updated.
67    cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68        println!(
69            ">> val-swap pattern fired with old={} and new={}!",
70            old, new
71        );
72        swap_val.send(new).unwrap();
73
74        old
75    });
76
77    // Declare a new Join Pattern that mentions the same channel multiple
78    // times, so if the val channel has sent two messages they will be
79    // combined into a single messages sent by a clone of val. This ensures
80    // that eventually, the storage cell will only keep a single value
81    // around.
82    cell.when(&val).and(&val).then_do(move |a, b| {
83        println!(">> val-val pattern fired with a={} and b={}!", a, b);
84        val_val.send(a + b).unwrap();
85    });
86
87    /* End of the Join Pattern setup. */
88
89    // Initialise the storage cell by sending an initial value that
90    // can be picked up in future executions of the above Join Patterns.
91    val.send(1729).unwrap();
92
93    // Request a value update if one is available.
94    put.send(42).unwrap();
95
96    // Send another value that will eventually get combined with the
97    // existing one.
98    val.send(1).unwrap();
99
100    // Request another value update.
101    put.send(22).unwrap();
102
103    // Request the current value of the storage cell and print it.
104    println!("get.recv()={}", get.recv().unwrap());
105
106    // Request a swap of the current value of the storage cell with a new
107    // one and print the old value that is retrieved as a result.
108    println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110    // Request the current value of the storage cell again and print it.
111    println!("get.recv()={}", get.recv().unwrap());
112}

Trait Implementations§

Source§

impl<R: Clone> Clone for RecvChannel<R>

Source§

fn clone(&self) -> RecvChannel<R>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<R> Freeze for RecvChannel<R>

§

impl<R> RefUnwindSafe for RecvChannel<R>
where R: RefUnwindSafe,

§

impl<R> Send for RecvChannel<R>
where R: Send,

§

impl<R> Sync for RecvChannel<R>
where R: Sync,

§

impl<R> Unpin for RecvChannel<R>
where R: Unpin,

§

impl<R> UnsafeUnpin for RecvChannel<R>

§

impl<R> UnwindSafe for RecvChannel<R>
where R: UnwindSafe,

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.