use mpstthree::binary::struct_trait::{end::End, session::Session}; use mpstthree::binary_atmp::struct_trait::{recv::RecvTimed, send::SendTimed}; use mpstthree::generate_atmp; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::random; use std::collections::HashMap; use std::error::Error; use std::time::Instant; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for four participants generate_atmp!(MeshedChannels, Api, Controller, Storage, User); // RoleApi enum Branching0fromCtoA { Up( MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, RoleController< RoleStorage< RoleStorage>>>>, >, >, NameApi, >, ), Down( MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, RoleController>>>>, NameApi, >, ), Close( MeshedChannels< RecvTimed, End, SendTimed, RoleController>, NameApi, >, ), } type Recurs0fromCtoA = RecvTimed; // RoleController type Choose0fromCtoA = ::Dual; type Choose0fromCtoS = ::Dual; type Choose0fromCtoU = ::Dual; // RoleStorage enum Branching0fromCtoS { Up( MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoS, End, RoleApi>>, NameStorage, >, ), Down( MeshedChannels< End, RecvTimed, End, RoleController>, NameStorage, >, ), Close( MeshedChannels< End, RecvTimed, End, RoleController, NameStorage, >, ), } type Recurs0fromCtoS = RecvTimed; // RoleUser enum Branching0fromCtoU { Up( MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Down( MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Close( MeshedChannels< RecvTimed, End, End, RoleApi, NameUser, >, ), } type Recurs0fromCtoU = RecvTimed; // Creating the MP sessions // RoleApi type EndpointApi0 = MeshedChannels< SendTimed, End, RecvTimed, RoleUser>>, NameApi, >; type EndpointApiInit = MeshedChannels< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, RecvTimed, RoleController>>>, NameApi, >; // RoleController type EndpointControllerDown = MeshedChannels< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed, Choose0fromCtoU, RoleApi>>, NameController, >; type EndpointControllerUp = MeshedChannels< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, Choose0fromCtoS, Choose0fromCtoU, RoleApi>, NameController, >; type EndpointControllerClose = MeshedChannels< SendTimed, SendTimed, End, RoleApi>, NameController, >; type EndpointController0 = MeshedChannels< RecvTimed, Choose0fromCtoS, Choose0fromCtoU, RoleApi, NameController, >; type EndpointControllerInit = MeshedChannels< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, Choose0fromCtoU, RoleStorage>>>, NameController, >; // RoleStorage type EndpointStorage0 = MeshedChannels, NameStorage>; type EndpointStorageInit = MeshedChannels< End, RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, RoleController>>, NameStorage, >; // RoleUser type EndpointUserInit = MeshedChannels< SendTimed, Recurs0fromCtoU, End, RoleApi>, NameUser, >; ///////////////////////// fn endpoint_api( s: EndpointApiInit, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); let (_start, s) = s.recv(all_clocks)?; recurs_api(s, all_clocks) } fn recurs_api( s: EndpointApi0, all_clocks: &mut HashMap, ) -> Result<(), Box> { let (request, s) = s.recv(all_clocks)?; let s = s.send(random(), all_clocks)?; offer_mpst!(s, all_clocks, { Branching0fromCtoA::Up(s) => { let (_up, s) = s.recv(all_clocks)?; let s = s.send(request, all_clocks)?; let (response, s) = s.recv(all_clocks)?; let s = s.send(response, all_clocks)?; recurs_api(s, all_clocks) }, Branching0fromCtoA::Down(s) => { let (failure, s) = s.recv(all_clocks)?; let s = s.send(failure, all_clocks)?; recurs_api(s, all_clocks) }, Branching0fromCtoA::Close(s) => { let (close, s) = s.recv(all_clocks)?; let s = s.send(close, all_clocks)?; s.close() }, }) } fn endpoint_controller( s: EndpointControllerInit, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); let s = s.send(LOOPS, all_clocks)?; let s = s.send(LOOPS, all_clocks)?; let (_hard_ping, s) = s.recv(all_clocks)?; recurs_controller(s, LOOPS, all_clocks) } fn recurs_controller( s: EndpointController0, loops: i32, all_clocks: &mut HashMap, ) -> Result<(), Box> { let (_get_mode, s) = s.recv(all_clocks)?; match loops { i if i < 0 => { let s: EndpointControllerClose = choose_mpst_controller_to_all!( s, all_clocks, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); let s = s.send(0, all_clocks)?; let s = s.send(0, all_clocks)?; s.close() } i if i % 2 == 0 => { let s: EndpointControllerUp = choose_mpst_controller_to_all!( s, all_clocks, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up ); let s = s.send(random(), all_clocks)?; recurs_controller(s, loops - 1, all_clocks) } _ => { let s: EndpointControllerDown = choose_mpst_controller_to_all!( s, all_clocks, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down ); let s = s.send(random(), all_clocks)?; let s = s.send(random(), all_clocks)?; recurs_controller(s, loops - 1, all_clocks) } } } fn endpoint_storage( s: EndpointStorageInit, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); let (_start, s) = s.recv(all_clocks)?; let s = s.send(random(), all_clocks)?; recurs_storage(s, all_clocks) } fn recurs_storage( s: EndpointStorage0, all_clocks: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s, all_clocks, { Branching0fromCtoS::Up(s) => { let (request, s) = s.recv(all_clocks)?; let s = s.send(request, all_clocks)?; recurs_storage(s, all_clocks) }, Branching0fromCtoS::Down(s) => { let (_failure, s) = s.recv(all_clocks)?; recurs_storage(s, all_clocks) }, Branching0fromCtoS::Close(s) => { let (_close, s) = s.recv(all_clocks)?; s.close() }, }) } fn endpoint_user( s: EndpointUserInit, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); let s = s.send(random(), all_clocks)?; offer_mpst!(s, all_clocks, { Branching0fromCtoU::Up(s) => { let (_response, s) = s.recv(all_clocks)?; endpoint_user(s, all_clocks) }, Branching0fromCtoU::Down(s) => { let (_failure, s) = s.recv(all_clocks)?; endpoint_user(s, all_clocks) }, Branching0fromCtoU::Close(s) => { let (_close, s) = s.recv(all_clocks)?; s.close() }, }) } ///////////////////////// static LOOPS: i32 = 100; fn main() { let (thread_api, thread_controller, thread_storage, thread_user) = fork_mpst( endpoint_api, endpoint_controller, endpoint_storage, endpoint_user, ); thread_api.join().unwrap(); thread_controller.join().unwrap(); thread_storage.join().unwrap(); thread_user.join().unwrap(); }