#![allow( clippy::large_enum_variant, clippy::type_complexity, clippy::too_many_arguments )] use criterion::{black_box, criterion_group, criterion_main, Criterion}; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::random; use std::error::Error; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for four participants generate!( "rec_and_cancel", MeshedChannels, Api, Controller, Storage, User ); // RoleApi enum Branching0fromCtoA { Up( MeshedChannels< Recv>, Send>, Send>, RoleController< RoleStorage< RoleStorage>>>>, >, >, NameApi, >, ), Down( MeshedChannels< Recv>, End, Send>, RoleController>>>>, NameApi, >, ), Close( MeshedChannels< Recv, End, Send, RoleController>, NameApi, >, ), } type Recurs0fromCtoA = Recv; // RoleController type Choose0fromCtoA = Send; type Choose0fromCtoS = Send; type Choose0fromCtoU = Send; // RoleStorage enum Branching0fromCtoS { Up( MeshedChannels< Recv>, Recurs0fromCtoS, End, RoleApi>>, NameStorage, >, ), Down( MeshedChannels< End, Recv, End, RoleController>, NameStorage, >, ), Close(MeshedChannels, End, RoleController, NameStorage>), } type Recurs0fromCtoS = Recv; // RoleUser enum Branching0fromCtoU { Up( MeshedChannels< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Down( MeshedChannels< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Close(MeshedChannels, End, End, RoleApi, NameUser>), } type Recurs0fromCtoU = Recv; // Creating the MP sessions // RoleApi type EndpointApi0 = MeshedChannels< Send, End, Recv, RoleUser>>, NameApi, >; type EndpointApiInit = MeshedChannels< Recv>, End, Recv, RoleController>>>, NameApi, >; // RoleController type EndpointControllerDown = MeshedChannels< Send>, Send, Choose0fromCtoU, RoleApi>>, NameController, >; type EndpointControllerUp = MeshedChannels< Send>, Choose0fromCtoS, Choose0fromCtoU, RoleApi>, NameController, >; type EndpointControllerClose = MeshedChannels< Send, Send, End, RoleApi>, NameController, >; type EndpointController0 = MeshedChannels< Recv, Choose0fromCtoS, Choose0fromCtoU, RoleApi, NameController, >; type EndpointControllerInit = MeshedChannels< Send>, Send>, Choose0fromCtoU, RoleStorage>>>, NameController, >; // RoleStorage type EndpointStorage0 = MeshedChannels, NameStorage>; type EndpointStorageInit = MeshedChannels< End, Recv>, End, RoleController>>, NameStorage, >; // RoleUser type EndpointUserInit = MeshedChannels< Send, Recurs0fromCtoU, End, RoleApi>, NameUser, >; ///////////////////////// 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: EndpointControllerInit) -> Result<(), Box> { let s = s.send(LOOPS)?; let s = s.send(LOOPS)?; let (_hard_ping, s) = s.recv()?; recurs_controller(s, LOOPS) } fn recurs_controller(s: EndpointController0, loops: i32) -> Result<(), Box> { let (_get_mode, s) = s.recv()?; match loops { i if i < 0 => { let s: EndpointControllerClose = choose_mpst_controller_to_all!( s, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); let s = s.send(0)?; let s = s.send(0)?; s.close() } i if i % 2 == 0 => { let s: EndpointControllerUp = choose_mpst_controller_to_all!( s, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up ); let s = s.send(random::())?; recurs_controller(s, loops - 1) } _ => { let s: EndpointControllerDown = choose_mpst_controller_to_all!( s, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down ); let s = s.send(random::())?; let s = s.send(random::())?; recurs_controller(s, loops - 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 aux() { let (thread_api, thread_controller, thread_storage, thread_user) = fork_mpst( black_box(endpoint_api), black_box(endpoint_controller), black_box(endpoint_storage), black_box(endpoint_user), ); thread_api.join().unwrap(); thread_controller.join().unwrap(); thread_storage.join().unwrap(); thread_user.join().unwrap(); } ///////////////////////// static LOOPS: i32 = 100; pub fn circuit_breaker(c: &mut Criterion) { c.bench_function("Circuit breaker AMPST", |b| b.iter(aux)); } ///////////////////////// criterion_group! { name = bench; config = Criterion::default().significance_level(0.05).without_plots().sample_size(100000); targets = circuit_breaker, } criterion_main! { bench }