use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{ choose_mpst_multi_to_all, close_mpst, create_meshedchannels, create_multiple_normal_name, create_multiple_normal_role, create_recv_mpst_session_bundle, create_send_mpst_cancel_bundle, fork_mpst_multi, offer_mpst, }; use rand::random; use std::error::Error; use std::marker; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for four participants create_meshedchannels!(MeshedChannels, 4); // Create Roles create_multiple_normal_role!( Api, DualAPI | Controller, DualController | Storage, DualStorage | User, DualUser | ); // Create Names create_multiple_normal_name!(NameApi, NameController, NameStorage, NameUser); // Create send create_send_mpst_cancel_bundle!( send_api_to_controller, Controller, 1 | send_api_to_storage, Storage, 2 | send_api_to_user, User, 3 | => NameApi, MeshedChannels, 4 ); create_send_mpst_cancel_bundle!( send_controller_to_api, Api, 1 | send_controller_to_storage, Storage, 2 | => NameController, MeshedChannels, 4 ); create_send_mpst_cancel_bundle!( send_storage_to_api, Api, 1 | send_storage_to_controller, Controller, 2 | => NameStorage, MeshedChannels, 4 ); create_send_mpst_cancel_bundle!( send_user_to_api, Api, 1 | => NameUser, MeshedChannels, 4 ); // Create recv create_recv_mpst_session_bundle!( recv_api_from_controller, Controller, 1 | recv_api_from_storage, Storage, 2 | recv_api_from_user, User, 3 | => NameApi, MeshedChannels, 4 ); create_recv_mpst_session_bundle!( recv_controller_from_api, Api, 1 | recv_controller_from_storage, Storage, 2 | => NameController, MeshedChannels, 4 ); create_recv_mpst_session_bundle!( recv_storage_from_api, Api, 1 | recv_storage_from_controller, Controller, 2 | => NameStorage, MeshedChannels, 4 ); create_recv_mpst_session_bundle!( recv_user_from_api, Api, 1 | recv_user_from_controller, Controller, 2 | => NameUser, MeshedChannels, 4 ); // Create close function close_mpst!(close_mpst_multi, MeshedChannels, 4); // Create fork function fork_mpst_multi!(fork_mpst, MeshedChannels, 4); // Api enum Branching0fromCtoA { Up( MeshedChannels< Recv>>, Send>, Send>, Controller>>>>>>, NameApi, >, ), Down( MeshedChannels< Recv>>, End, Send>, Controller>>>>, NameApi, >, ), Close(MeshedChannels, End, Send, Controller>, NameApi>), } type Recurs0fromCtoA = Recv, End>; // Controller type Choose0fromCtoA = Send, End>; type Choose0fromCtoS = Send, End>; type Choose0fromCtoU = Send, End>; // Storage enum Branching0fromCtoS { Up( MeshedChannels< Recv>, Recurs0fromCtoS, End, Api>>, NameStorage, >, ), Down( MeshedChannels< End, Recv>, End, Controller>, NameStorage, >, ), Close(MeshedChannels, End, Controller, NameStorage>), } type Recurs0fromCtoS = Recv, End>; // User enum Branching0fromCtoU { Up( MeshedChannels< Recv>, Recurs0fromCtoU, End, Api>>, NameUser, >, ), Down( MeshedChannels< Recv>, Recurs0fromCtoU, End, Api>>, NameUser, >, ), Close(MeshedChannels, End, End, Api, NameUser>), } type Recurs0fromCtoU = Recv, End>; // Creating the MP sessions // Api type EndpointApi0 = MeshedChannels< Send>, End, Recv, User>>, NameApi, >; type EndpointApiInit = MeshedChannels< Recv>>, End, Recv, Controller>>>, NameApi, >; // Controller type EndpointController0 = MeshedChannels< Recv>, Choose0fromCtoS, Choose0fromCtoU, Api, NameController, >; type EndpointControllerInit = MeshedChannels< Send>>, Send>>, Choose0fromCtoU, Storage>>>, NameController, >; // Storage type EndpointStorage0 = MeshedChannels, End, Controller, NameStorage>; type EndpointStorageInit = MeshedChannels< End, Recv>>, End, Controller>>, NameStorage, >; // User type EndpointUserInit = MeshedChannels, Recurs0fromCtoU, End, Api>, NameUser>; ///////////////////////// fn endpoint_api(s: EndpointApiInit) -> Result<(), Box> { let (_start, s) = recv_api_from_controller(s)?; recurs_api(s) } fn recurs_api(s: EndpointApi0) -> Result<(), Box> { let (request, s) = recv_api_from_user(s)?; let s = send_api_to_controller(random::(), s)?; offer_mpst!(s, recv_api_from_controller, { Branching0fromCtoA::Up(s) => { let (_up, s) = recv_api_from_controller(s)?; let s = send_api_to_storage(request, s)?; let (response, s) = recv_api_from_storage(s)?; let s = send_api_to_user(response, s)?; recurs_api(s) }, Branching0fromCtoA::Down(s) => { let (failure, s) = recv_api_from_controller(s)?; let s = send_api_to_user(failure, s)?; recurs_api(s) }, Branching0fromCtoA::Close(s) => { let (close, s) = recv_api_from_controller(s)?; let s = send_api_to_user(close, s)?; close_mpst_multi(s) }, }) } fn endpoint_controller(s: EndpointControllerInit) -> Result<(), Box> { let s = send_controller_to_storage(100, s)?; let s = send_controller_to_api(100, s)?; let (_hard_ping, s) = recv_controller_from_storage(s)?; recurs_controller(s, 100) } fn recurs_controller(s: EndpointController0, loops: i32) -> Result<(), Box> { let (_get_mode, s) = recv_controller_from_api(s)?; match loops { i if i < 0 => { let s = choose_mpst_multi_to_all!( s, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close, => NameController, MeshedChannels, 2 ); let s = send_controller_to_api(0, s)?; let s = send_controller_to_storage(0, s)?; close_mpst_multi(s) } i if i % 2 == 0 => { let s = choose_mpst_multi_to_all!( s, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up, => NameController, MeshedChannels, 2 ); let s = send_controller_to_api(random::(), s)?; recurs_controller(s, loops - 1) } _ => { let s = choose_mpst_multi_to_all!( s, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down, => NameController, MeshedChannels, 2 ); let s = send_controller_to_api(random::(), s)?; let s = send_controller_to_storage(random::(), s)?; recurs_controller(s, loops - 1) } } } fn endpoint_storage(s: EndpointStorageInit) -> Result<(), Box> { let (_start, s) = recv_storage_from_controller(s)?; let s = send_storage_to_controller(random::(), s)?; recurs_storage(s) } fn recurs_storage(s: EndpointStorage0) -> Result<(), Box> { offer_mpst!(s, recv_storage_from_controller, { Branching0fromCtoS::Up(s) => { let (request, s) = recv_storage_from_api(s)?; let s = send_storage_to_api(request, s)?; recurs_storage(s) }, Branching0fromCtoS::Down(s) => { let (_failure, s) = recv_storage_from_controller(s)?; recurs_storage(s) }, Branching0fromCtoS::Close(s) => { let (_close, s) = recv_storage_from_controller(s)?; close_mpst_multi(s) }, }) } fn endpoint_user(s: EndpointUserInit) -> Result<(), Box> { let s = send_user_to_api(random::(), s)?; offer_mpst!(s, recv_user_from_controller, { Branching0fromCtoU::Up(s) => { let (_response, s) = recv_user_from_api(s)?; endpoint_user(s) }, Branching0fromCtoU::Down(s) => { let (_failure, s) = recv_user_from_api(s)?; endpoint_user(s) }, Branching0fromCtoU::Close(s) => { let (_close, s) = recv_user_from_api(s)?; close_mpst_multi(s) }, }) } ///////////////////////// 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(); }