use mpstthree::binary::struct_trait::{end::End, session::Session}; use mpstthree::binary_atmp::struct_trait::{recv::RecvTimed, send::SendTimed}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::{random, thread_rng, Rng}; use std::collections::HashMap; use std::error::Error; use std::time::Instant; // CB = circuit breaker generate!( "atmp_interleaved", MeshedChannelsFour, Api, ControllerCB, Storage, User, 2, MeshedChannelsTwo, ControllerLog, Logs, 1, fork_mpst ); // RoleApi enum Branching0fromCtoA { Up( MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, RoleControllerCB< RoleStorage< RoleStorage>>>>, >, >, NameApi, >, ), Down( MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, RoleControllerCB>>>>, NameApi, >, ), Close( MeshedChannelsFour< RecvTimed, End, SendTimed, RoleControllerCB>, NameApi, >, ), } type Recurs0fromCtoA = RecvTimed; // RoleControllerCB type Choose0fromCtoA = ::Dual; type Choose0fromCtoS = ::Dual; type Choose0fromCtoU = ::Dual; // RoleStorage enum Branching0fromCtoS { Up( MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoS, End, RoleApi>>, NameStorage, >, ), Down( MeshedChannelsFour< End, RecvTimed, End, RoleControllerCB>, NameStorage, >, ), Close( MeshedChannelsFour< End, RecvTimed, End, RoleControllerCB, NameStorage, >, ), } type Recurs0fromCtoS = RecvTimed; // RoleUser enum Branching0fromCtoU { Up( MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Down( MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Close( MeshedChannelsFour< RecvTimed, End, End, RoleApi, NameUser, >, ), } type Recurs0fromCtoU = RecvTimed; // RoleControllerLog enum Branching0fromLtoC { Success( MeshedChannelsTwo< RecvTimed, RoleLogs>, NameControllerLog, >, ), Failure( MeshedChannelsTwo< RecvTimed, RoleLogs, NameControllerLog, >, ), } type Recurs0fromCtoL = RecvTimed; type Choose1fromCtoL = ::Dual; // RoleLogs type Choose0fromLtoC = SendTimed; enum Branching1fromCtoL { Restart( MeshedChannelsTwo< RecvTimed, RoleControllerLog, NameLogs, >, ), Stop( MeshedChannelsTwo< RecvTimed, RoleControllerLog, NameLogs, >, ), } type Recurs1fromLtoC = RecvTimed; // Creating the MP sessions // RoleApi type EndpointApi0 = MeshedChannelsFour< SendTimed, End, RecvTimed, RoleUser>>, NameApi, >; type EndpointApiInit = MeshedChannelsFour< RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, RecvTimed, RoleControllerCB>>>, NameApi, >; // RoleControllerCB type EndpointCBControllerDown = MeshedChannelsFour< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed, Choose0fromCtoU, RoleApi>>, NameControllerCB, >; type EndpointCBControllerUp = MeshedChannelsFour< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, Choose0fromCtoS, Choose0fromCtoU, RoleApi>, NameControllerCB, >; type EndpointCBControllerClose = MeshedChannelsFour< SendTimed, SendTimed, End, RoleApi>, NameControllerCB, >; type EndpointCBController0 = MeshedChannelsFour< RecvTimed, Choose0fromCtoS, Choose0fromCtoU, RoleApi, NameControllerCB, >; type EndpointCBControllerInit = MeshedChannelsFour< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, Choose0fromCtoU, RoleStorage>>>, NameControllerCB, >; type EndpointLogController1Stop = MeshedChannelsTwo< SendTimed, RoleLogs, NameControllerLog, >; type EndpointLogController1Restart = MeshedChannelsTwo< SendTimed, RoleLogs>, NameControllerLog, >; type EndpointLogController0 = MeshedChannelsTwo, NameControllerLog>; type EndpointLogController1 = MeshedChannelsTwo; type EndpointLogControllerInit = MeshedChannelsTwo< SendTimed, RoleLogs>, NameControllerLog, >; // RoleStorage type EndpointStorage0 = MeshedChannelsFour, NameStorage>; type EndpointStorageInit = MeshedChannelsFour< End, RecvTimed< i32, 'a', 0, true, 10, true, ' ', SendTimed, >, End, RoleControllerCB>>, NameStorage, >; // RoleUser type EndpointUserInit = MeshedChannelsFour< SendTimed, Recurs0fromCtoU, End, RoleApi>, NameUser, >; // RoleLogs type EndpointLogs0Success = MeshedChannelsTwo< SendTimed, RoleControllerLog, NameLogs, >; type EndpointLogs0Failure = MeshedChannelsTwo< SendTimed, RoleControllerLog>, NameLogs, >; type EndpointLogs0 = MeshedChannelsTwo; type EndpointLogs1 = MeshedChannelsTwo, NameLogs>; type EndpointLogsInit = MeshedChannelsTwo< RecvTimed, RoleControllerLog, NameLogs, >; ///////////////////////// 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_circuit_breaker: EndpointCBControllerInit, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogControllerInit, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { all_clocks_circuit_breaker.insert('a', Instant::now()); all_clocks_logging.insert('a', Instant::now()); let start_circuit_breaker: i32 = thread_rng().gen_range(50..100); let s_circuit_breaker = s_circuit_breaker.send(start_circuit_breaker, all_clocks_circuit_breaker)?; let s_circuit_breaker = s_circuit_breaker.send(start_circuit_breaker, all_clocks_circuit_breaker)?; let (_hard_ping, s_circuit_breaker) = s_circuit_breaker.recv(all_clocks_circuit_breaker)?; let start_logging: i32 = thread_rng().gen_range(50..100); let s_logging = s_logging.send(start_logging, all_clocks_logging)?; recurs_controller( s_circuit_breaker, start_circuit_breaker, all_clocks_circuit_breaker, s_logging, start_logging, all_clocks_logging, ) } fn recurs_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogController0, loops_logging: i32, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { let (_get_mode, s_circuit_breaker) = s_circuit_breaker.recv(all_clocks_circuit_breaker)?; match loops_circuit_breaker { i if i < 0 => { let s_circuit_breaker: EndpointCBControllerClose = choose_mpst_controllercb_to_all!( s_circuit_breaker, all_clocks_circuit_breaker, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); recurs_1_controller_end( s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging, ) } i if i % 2 == 0 => { let s_circuit_breaker: EndpointCBControllerUp = choose_mpst_controllercb_to_all!( s_circuit_breaker, all_clocks_circuit_breaker, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up ); let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; recurs_1_controller( s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging, ) } _ => { let s_circuit_breaker: EndpointCBControllerDown = choose_mpst_controllercb_to_all!( s_circuit_breaker, all_clocks_circuit_breaker, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down ); let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; recurs_1_controller( s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging, ) } } } fn recurs_1_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogController0, loops_logging: i32, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s_logging, all_clocks_logging, { Branching0fromLtoC::Success(s_logging) => { let (_, s_logging) = s_logging.recv(all_clocks_logging)?; recurs_controller(s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging) }, Branching0fromLtoC::Failure(s_logging) => { let (_, s_logging) = s_logging.recv(all_clocks_logging)?; recurs_2_controller(s_circuit_breaker, loops_circuit_breaker, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging) }, }) } fn recurs_2_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogController1, loops_logging: i32, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { match loops_logging { i if i <= 0 => { // Stop let s_logging: EndpointLogController1Stop = choose_mpst_controllerlog_to_all!( s_logging, all_clocks_logging, Branching1fromCtoL::Stop ); let s_logging = s_logging.send(loops_logging - 1, all_clocks_logging)?; let (_get_mode, s_circuit_breaker) = s_circuit_breaker.recv(all_clocks_circuit_breaker)?; let s_circuit_breaker: EndpointCBControllerClose = choose_mpst_controllercb_to_all!( s_circuit_breaker, all_clocks_circuit_breaker, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; s_circuit_breaker.close()?; s_logging.close() } _ => { // Restart let s_logging: EndpointLogController1Restart = choose_mpst_controllerlog_to_all!( s_logging, all_clocks_logging, Branching1fromCtoL::Restart ); let s_logging = s_logging.send(loops_logging - 1, all_clocks_logging)?; recurs_controller( s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging - 1, all_clocks_logging, ) } } } fn recurs_1_controller_end( s_circuit_breaker: EndpointCBControllerClose, loops_circuit_breaker: i32, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogController0, loops_logging: i32, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s_logging, all_clocks_logging, { Branching0fromLtoC::Success(s_logging) => { let (_, s_logging) = s_logging.recv(all_clocks_logging)?; recurs_1_controller_end(s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging) }, Branching0fromLtoC::Failure(s_logging) => { let (_, s_logging) = s_logging.recv(all_clocks_logging)?; recurs_2_controller_end(s_circuit_breaker, loops_circuit_breaker, all_clocks_circuit_breaker, s_logging, loops_logging, all_clocks_logging) }, }) } fn recurs_2_controller_end( s_circuit_breaker: EndpointCBControllerClose, loops_circuit_breaker: i32, all_clocks_circuit_breaker: &mut HashMap, s_logging: EndpointLogController1, loops_logging: i32, all_clocks_logging: &mut HashMap, ) -> Result<(), Box> { match loops_logging { i if i <= 0 => { // Stop let s_logging: EndpointLogController1Stop = choose_mpst_controllerlog_to_all!( s_logging, all_clocks_logging, Branching1fromCtoL::Stop ); let s_logging = s_logging.send(loops_logging - 1, all_clocks_logging)?; let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; let s_circuit_breaker = s_circuit_breaker.send(random(), all_clocks_circuit_breaker)?; s_circuit_breaker.close()?; s_logging.close() } _ => { // Restart let s_logging: EndpointLogController1Restart = choose_mpst_controllerlog_to_all!( s_logging, all_clocks_logging, Branching1fromCtoL::Restart ); let s_logging = s_logging.send(loops_logging - 1, all_clocks_logging)?; recurs_1_controller_end( s_circuit_breaker, loops_circuit_breaker - 1, all_clocks_circuit_breaker, s_logging, loops_logging - 1, all_clocks_logging, ) } } } 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() }, }) } fn endpoint_logs( s: EndpointLogsInit, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); let (status, s) = s.recv(all_clocks)?; recurs_0_logs(s, status, all_clocks) } fn recurs_0_logs( s: EndpointLogs0, loops: i32, all_clocks: &mut HashMap, ) -> Result<(), Box> { match loops { i if i % 2 == 0 && i > 0 => { // Success let s: EndpointLogs0Success = choose_mpst_logs_to_all!(s, all_clocks, Branching0fromLtoC::Success); let s = s.send(loops - 1, all_clocks)?; recurs_0_logs(s, loops - 1, all_clocks) } _ => { // Failure let s: EndpointLogs0Failure = choose_mpst_logs_to_all!(s, all_clocks, Branching0fromLtoC::Failure); let s = s.send(loops - 1, all_clocks)?; recurs_1_logs(s, all_clocks) } } } fn recurs_1_logs( s: EndpointLogs1, all_clocks: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s, all_clocks, { Branching1fromCtoL::Restart(s) => { let (loops, s) = s.recv(all_clocks)?; recurs_0_logs(s, loops - 1, all_clocks) }, Branching1fromCtoL::Stop(s) => { let (_, s) = s.recv(all_clocks)?; s.close() }, }) } ///////////////////////// fn main() { let (thread_api, thread_storage, thread_user, thread_logs, thread_controller) = fork_mpst( endpoint_api, endpoint_storage, endpoint_user, endpoint_logs, endpoint_controller, ); thread_api.join().unwrap(); thread_controller.join().unwrap(); thread_storage.join().unwrap(); thread_user.join().unwrap(); thread_logs.join().unwrap(); }