use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{generate, offer_mpst}; use rand::{random, thread_rng, Rng}; use std::error::Error; use std::marker; // CB = circuit breaker generate!( "interleaved", MeshedChannelsFour, Api, ControllerCB, Storage, User, 2, MeshedChannelsTwo, ControllerLog, Logs, 1, fork_mpst ); // RoleApi enum Branching0fromCtoA { Up( MeshedChannelsFour< Recv>>, Send>, Send>, RoleControllerCB< RoleStorage< RoleStorage>>>>, >, >, NameApi, >, ), Down( MeshedChannelsFour< Recv>>, End, Send>, RoleControllerCB>>>>, NameApi, >, ), Close( MeshedChannelsFour< Recv, End, Send, RoleControllerCB>, NameApi, >, ), } type Recurs0fromCtoA = Recv, End>; // RoleControllerCB type Choose0fromCtoA = Send, End>; type Choose0fromCtoS = Send, End>; type Choose0fromCtoU = Send, End>; // RoleStorage enum Branching0fromCtoS { Up( MeshedChannelsFour< Recv>, Recurs0fromCtoS, End, RoleApi>>, NameStorage, >, ), Down( MeshedChannelsFour< End, Recv>, End, RoleControllerCB>, NameStorage, >, ), Close(MeshedChannelsFour, End, RoleControllerCB, NameStorage>), } type Recurs0fromCtoS = Recv, End>; // RoleUser enum Branching0fromCtoU { Up( MeshedChannelsFour< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Down( MeshedChannelsFour< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Close(MeshedChannelsFour, End, End, RoleApi, NameUser>), } type Recurs0fromCtoU = Recv, End>; // RoleControllerLog enum Branching0fromLtoC { Success( MeshedChannelsTwo< Recv>, RoleLogs>, NameControllerLog, >, ), Failure( MeshedChannelsTwo>, RoleLogs, NameControllerLog>, ), } type Recurs0fromCtoL = Recv, End>; type Choose1fromCtoL = Send, End>; // RoleLogs type Choose0fromLtoC = Send, End>; enum Branching1fromCtoL { Restart( MeshedChannelsTwo>, RoleControllerLog, NameLogs>, ), Stop(MeshedChannelsTwo, RoleControllerLog, NameLogs>), } type Recurs1fromLtoC = Recv, End>; // Creating the MP sessions // RoleApi type EndpointApi0 = MeshedChannelsFour< Send>, End, Recv, RoleUser>>, NameApi, >; type EndpointApiInit = MeshedChannelsFour< Recv>>, End, Recv, RoleControllerCB>>>, NameApi, >; // RoleControllerCB type EndpointCBControllerDown = MeshedChannelsFour< Send>>, Send>, Choose0fromCtoU, RoleApi>>, NameControllerCB, >; type EndpointCBControllerUp = MeshedChannelsFour< Send>>, Choose0fromCtoS, Choose0fromCtoU, RoleApi>, NameControllerCB, >; type EndpointCBControllerClose = MeshedChannelsFour< Send, Send, End, RoleApi>, NameControllerCB, >; type EndpointCBController0 = MeshedChannelsFour< Recv>, Choose0fromCtoS, Choose0fromCtoU, RoleApi, NameControllerCB, >; type EndpointCBControllerInit = MeshedChannelsFour< Send>>, Send>>, Choose0fromCtoU, RoleStorage>>>, NameControllerCB, >; type EndpointLogController1Stop = MeshedChannelsTwo, RoleLogs, NameControllerLog>; type EndpointLogController1Restart = MeshedChannelsTwo>, RoleLogs>, NameControllerLog>; type EndpointLogController0 = MeshedChannelsTwo, RoleLogs, NameControllerLog>; type EndpointLogController1 = MeshedChannelsTwo, RoleBroadcast, NameControllerLog>; type EndpointLogControllerInit = MeshedChannelsTwo>, RoleLogs>, NameControllerLog>; // RoleStorage type EndpointStorage0 = MeshedChannelsFour, End, RoleControllerCB, NameStorage>; type EndpointStorageInit = MeshedChannelsFour< End, Recv>>, End, RoleControllerCB>>, NameStorage, >; // RoleUser type EndpointUserInit = MeshedChannelsFour< Send, Recurs0fromCtoU, End, RoleApi>, NameUser, >; // RoleLogs type EndpointLogs0Success = MeshedChannelsTwo>, RoleControllerLog, NameLogs>; type EndpointLogs0Failure = MeshedChannelsTwo< Send>, RoleControllerLog>, NameLogs, >; type EndpointLogs0 = MeshedChannelsTwo, RoleBroadcast, NameLogs>; type EndpointLogs1 = MeshedChannelsTwo, RoleControllerLog, NameLogs>; type EndpointLogsInit = MeshedChannelsTwo>, RoleControllerLog, NameLogs>; ///////////////////////// fn endpoint_api(s: EndpointApiInit) -> Result<(), Box> { let (_start, s) = s.recv()?; recurs_api(s) } fn recurs_api(s: EndpointApi0) -> Result<(), Box> { let (request, s) = s.recv()?; let s = s.send(random::())?; offer_mpst!(s, { Branching0fromCtoA::Up(s) => { let (_up, s) = s.recv()?; let s = s.send(request)?; let (response, s) = s.recv()?; let s = s.send(response)?; recurs_api(s) }, Branching0fromCtoA::Down(s) => { let (failure, s) = s.recv()?; let s = s.send(failure)?; recurs_api(s) }, Branching0fromCtoA::Close(s) => { let (close, s) = s.recv()?; let s = s.send(close)?; s.close() }, }) } fn endpoint_controller( s_circuit_breaker: EndpointCBControllerInit, s_logging: EndpointLogControllerInit, ) -> Result<(), Box> { let start_circuit_breaker: i32 = thread_rng().gen_range(50..100); let s_circuit_breaker = s_circuit_breaker.send(start_circuit_breaker)?; let s_circuit_breaker = s_circuit_breaker.send(start_circuit_breaker)?; let (_hard_ping, s_circuit_breaker) = s_circuit_breaker.recv()?; let start_logging: i32 = thread_rng().gen_range(50..100); let s_logging = s_logging.send(start_logging)?; recurs_controller( s_circuit_breaker, start_circuit_breaker, s_logging, start_logging, ) } fn recurs_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, s_logging: EndpointLogController0, loops_logging: i32, ) -> Result<(), Box> { let (_get_mode, s_circuit_breaker) = s_circuit_breaker.recv()?; match loops_circuit_breaker { i if i < 0 => { let s_circuit_breaker: EndpointCBControllerClose = choose_mpst_controllercb_to_all!( s_circuit_breaker, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); recurs_1_controller_end( s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging, ) } i if i % 2 == 0 => { let s_circuit_breaker: EndpointCBControllerUp = choose_mpst_controllercb_to_all!( s_circuit_breaker, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up ); let s_circuit_breaker = s_circuit_breaker.send(random::())?; recurs_1_controller( s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging, ) } _ => { let s_circuit_breaker: EndpointCBControllerDown = choose_mpst_controllercb_to_all!( s_circuit_breaker, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down ); let s_circuit_breaker = s_circuit_breaker.send(random::())?; let s_circuit_breaker = s_circuit_breaker.send(random::())?; recurs_1_controller( s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging, ) } } } fn recurs_1_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, s_logging: EndpointLogController0, loops_logging: i32, ) -> Result<(), Box> { offer_mpst!(s_logging, { Branching0fromLtoC::Success(s_logging) => { let (_, s_logging) = s_logging.recv()?; recurs_controller(s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging) }, Branching0fromLtoC::Failure(s_logging) => { let (_, s_logging) = s_logging.recv()?; recurs_2_controller(s_circuit_breaker, loops_circuit_breaker, s_logging, loops_logging) }, }) } fn recurs_2_controller( s_circuit_breaker: EndpointCBController0, loops_circuit_breaker: i32, s_logging: EndpointLogController1, loops_logging: i32, ) -> Result<(), Box> { match loops_logging { i if i <= 0 => { // Stop let s_logging: EndpointLogController1Stop = choose_mpst_controllerlog_to_all!(s_logging, Branching1fromCtoL::Stop); let s_logging = s_logging.send(loops_logging - 1)?; let (_get_mode, s_circuit_breaker) = s_circuit_breaker.recv()?; let s_circuit_breaker: EndpointCBControllerClose = choose_mpst_controllercb_to_all!( s_circuit_breaker, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); let s_circuit_breaker = s_circuit_breaker.send(random::())?; let s_circuit_breaker = s_circuit_breaker.send(random::())?; s_circuit_breaker.close()?; s_logging.close() } _ => { // Restart let s_logging: EndpointLogController1Restart = choose_mpst_controllerlog_to_all!(s_logging, Branching1fromCtoL::Restart); let s_logging = s_logging.send(loops_logging - 1)?; recurs_controller( s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging - 1, ) } } } fn recurs_1_controller_end( s_circuit_breaker: EndpointCBControllerClose, loops_circuit_breaker: i32, s_logging: EndpointLogController0, loops_logging: i32, ) -> Result<(), Box> { offer_mpst!(s_logging, { Branching0fromLtoC::Success(s_logging) => { let (_, s_logging) = s_logging.recv()?; recurs_1_controller_end(s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging) }, Branching0fromLtoC::Failure(s_logging) => { let (_, s_logging) = s_logging.recv()?; recurs_2_controller_end(s_circuit_breaker, loops_circuit_breaker, s_logging, loops_logging) }, }) } fn recurs_2_controller_end( s_circuit_breaker: EndpointCBControllerClose, loops_circuit_breaker: i32, s_logging: EndpointLogController1, loops_logging: i32, ) -> Result<(), Box> { match loops_logging { i if i <= 0 => { // Stop let s_logging: EndpointLogController1Stop = choose_mpst_controllerlog_to_all!(s_logging, Branching1fromCtoL::Stop); let s_logging = s_logging.send(loops_logging - 1)?; let s_circuit_breaker = s_circuit_breaker.send(random::())?; let s_circuit_breaker = s_circuit_breaker.send(random::())?; s_circuit_breaker.close()?; s_logging.close() } _ => { // Restart let s_logging: EndpointLogController1Restart = choose_mpst_controllerlog_to_all!(s_logging, Branching1fromCtoL::Restart); let s_logging = s_logging.send(loops_logging - 1)?; recurs_1_controller_end( s_circuit_breaker, loops_circuit_breaker - 1, s_logging, loops_logging - 1, ) } } } fn endpoint_storage(s: EndpointStorageInit) -> Result<(), Box> { let (_start, s) = s.recv()?; let s = s.send(random::())?; recurs_storage(s) } fn recurs_storage(s: EndpointStorage0) -> Result<(), Box> { offer_mpst!(s, { Branching0fromCtoS::Up(s) => { let (request, s) = s.recv()?; let s = s.send(request)?; recurs_storage(s) }, Branching0fromCtoS::Down(s) => { let (_failure, s) = s.recv()?; recurs_storage(s) }, Branching0fromCtoS::Close(s) => { let (_close, s) = s.recv()?; s.close() }, }) } fn endpoint_user(s: EndpointUserInit) -> Result<(), Box> { let s = s.send(random::())?; offer_mpst!(s, { Branching0fromCtoU::Up(s) => { let (_response, s) = s.recv()?; endpoint_user(s) }, Branching0fromCtoU::Down(s) => { let (_failure, s) = s.recv()?; endpoint_user(s) }, Branching0fromCtoU::Close(s) => { let (_close, s) = s.recv()?; s.close() }, }) } fn endpoint_logs(s: EndpointLogsInit) -> Result<(), Box> { let (status, s) = s.recv()?; recurs_0_logs(s, status) } fn recurs_0_logs(s: EndpointLogs0, loops: i32) -> Result<(), Box> { match loops { i if i % 2 == 0 && i > 0 => { // Success let s: EndpointLogs0Success = choose_mpst_logs_to_all!(s, Branching0fromLtoC::Success); let s = s.send(loops - 1)?; recurs_0_logs(s, loops - 1) } _ => { // Failure let s: EndpointLogs0Failure = choose_mpst_logs_to_all!(s, Branching0fromLtoC::Failure); let s = s.send(loops - 1)?; recurs_1_logs(s) } } } fn recurs_1_logs(s: EndpointLogs1) -> Result<(), Box> { offer_mpst!(s, { Branching1fromCtoL::Restart(s) => { let (loops, s) = s.recv()?; recurs_0_logs(s, loops - 1) }, Branching1fromCtoL::Stop(s) => { let (_, s) = s.recv()?; 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(); }