@@ -160,7 +160,54 @@ pub fn _protocol_start(
160160 cl : CoLink ,
161161 user_funcs : HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > ,
162162) -> Result < ( ) , Error > {
163+ let mut operator_funcs: HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > = HashMap :: new ( ) ;
164+ let mut protocols = vec ! [ ] ;
163165 for ( protocol_and_role, user_func) in user_funcs {
166+ let cl = cl. clone ( ) ;
167+ if protocol_and_role. ends_with ( ":@init" ) {
168+ let protocol_name = protocol_and_role[ ..protocol_and_role. len ( ) - 6 ] . to_string ( ) ;
169+ let _ = tokio:: runtime:: Builder :: new_multi_thread ( )
170+ . enable_all ( )
171+ . build ( )
172+ . unwrap ( )
173+ . block_on ( async move {
174+ let is_initialized_key =
175+ format ! ( "_internal:protocols:{}:_is_initialized" , protocol_name) ;
176+ let lock = cl. lock ( & is_initialized_key) . await ?;
177+ let res = cl. read_entry ( & is_initialized_key) . await ;
178+ if res. is_err ( ) || res. unwrap ( ) [ 0 ] == 0 {
179+ let cl_clone = cl. clone ( ) ;
180+ match user_func
181+ . start ( cl_clone, Default :: default ( ) , Default :: default ( ) )
182+ . await
183+ {
184+ Ok ( _) => { }
185+ Err ( e) => error ! ( "{}: {}." , protocol_and_role, e) ,
186+ }
187+ cl. update_entry ( & is_initialized_key, & [ 1 ] ) . await ?;
188+ }
189+ cl. unlock ( lock) . await ?;
190+ Ok :: < ( ) , Box < dyn std:: error:: Error + Send + Sync + ' static > > ( ( ) )
191+ } ) ;
192+ } else {
193+ protocols. push ( protocol_and_role[ ..protocol_and_role. rfind ( ':' ) . unwrap ( ) ] . to_string ( ) ) ;
194+ operator_funcs. insert ( protocol_and_role, user_func) ;
195+ }
196+ }
197+ let cl_clone = cl. clone ( ) ;
198+ let _ = tokio:: runtime:: Builder :: new_multi_thread ( )
199+ . enable_all ( )
200+ . build ( )
201+ . unwrap ( )
202+ . block_on ( async move {
203+ for protocol_name in protocols {
204+ let is_initialized_key =
205+ format ! ( "_internal:protocols:{}:_is_initialized" , protocol_name) ;
206+ cl_clone. update_entry ( & is_initialized_key, & [ 1 ] ) . await ?;
207+ }
208+ Ok :: < ( ) , Box < dyn std:: error:: Error + Send + Sync + ' static > > ( ( ) )
209+ } ) ;
210+ for ( protocol_and_role, user_func) in operator_funcs {
164211 let cl = cl. clone ( ) ;
165212 thread:: spawn ( || {
166213 tokio:: runtime:: Builder :: new_multi_thread ( )
0 commit comments