@@ -25,21 +25,21 @@ pub struct CoLinkProtocol {
2525 protocol_and_role : String ,
2626 cl : CoLink ,
2727 user_func : Box < dyn ProtocolEntry > ,
28- vt_public_addr : Option < String > ,
28+ args : CoLinkProtocolCommandLineArgs ,
2929}
3030
3131impl CoLinkProtocol {
3232 pub fn new (
3333 protocol_and_role : & str ,
3434 cl : CoLink ,
3535 user_func : Box < dyn ProtocolEntry > ,
36- vt_public_addr : Option < String > ,
36+ args : CoLinkProtocolCommandLineArgs ,
3737 ) -> Self {
3838 Self {
3939 protocol_and_role : protocol_and_role. to_string ( ) ,
4040 cl,
4141 user_func,
42- vt_public_addr ,
42+ args ,
4343 }
4444 }
4545
@@ -78,11 +78,20 @@ impl CoLinkProtocol {
7878 {
7979 cl. vt_p2p_ctx =
8080 Arc :: new ( crate :: extensions:: variable_transfer:: p2p_inbox:: VtP2pCtx {
81- public_addr : self . vt_public_addr . clone ( ) ,
81+ public_addr : self . args . vt_public_addr . clone ( ) ,
8282 ..Default :: default ( )
8383 } ) ;
8484 }
8585 let cl_clone = cl. clone ( ) ;
86+ let instance_id = match & self . args . instance_id {
87+ Some ( instance_id) => instance_id,
88+ None => "anonymous" ,
89+ } ;
90+ cl. update_entry (
91+ & format ! ( "_internal:task_po_mapping:{}" , task. task_id) ,
92+ instance_id. as_bytes ( ) ,
93+ )
94+ . await ?;
8695 match self
8796 . user_func
8897 . start ( cl, task. protocol_param , task. participants )
@@ -170,8 +179,7 @@ impl CoLinkProtocol {
170179pub fn _protocol_start (
171180 cl : CoLink ,
172181 user_funcs : HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > ,
173- keep_alive_when_disconnect : bool ,
174- vt_public_addr : Option < String > ,
182+ args : CoLinkProtocolCommandLineArgs ,
175183) -> Result < ( ) , Error > {
176184 let mut operator_funcs: HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > = HashMap :: new ( ) ;
177185 let mut protocols = HashSet :: new ( ) ;
@@ -233,14 +241,14 @@ pub fn _protocol_start(
233241 let mut threads = vec ! [ ] ;
234242 for ( protocol_and_role, user_func) in operator_funcs {
235243 let cl = cl. clone ( ) ;
236- let vt_public_addr = vt_public_addr . clone ( ) ;
244+ let args = args . clone ( ) ;
237245 threads. push ( thread:: spawn ( || {
238246 tokio:: runtime:: Builder :: new_multi_thread ( )
239247 . enable_all ( )
240248 . build ( )
241249 . unwrap ( )
242250 . block_on ( async move {
243- match CoLinkProtocol :: new ( & protocol_and_role, cl, user_func, vt_public_addr )
251+ match CoLinkProtocol :: new ( & protocol_and_role, cl, user_func, args )
244252 . start ( )
245253 . await
246254 {
@@ -250,7 +258,36 @@ pub fn _protocol_start(
250258 } ) ;
251259 } ) ) ;
252260 }
253- if keep_alive_when_disconnect {
261+ if args. enable_heartbeat {
262+ let cl = cl. clone ( ) ;
263+ if let Some ( instance_id) = args. instance_id {
264+ thread:: spawn ( || {
265+ tokio:: runtime:: Builder :: new_multi_thread ( )
266+ . enable_all ( )
267+ . build ( )
268+ . unwrap ( )
269+ . block_on ( async move {
270+ loop {
271+ let timestamp = chrono:: Utc :: now ( ) . timestamp_nanos ( ) ;
272+ let _ = cl
273+ . update_entry (
274+ & format ! (
275+ "_internal:protocol_operator_instances:{}:heartbeat" ,
276+ instance_id
277+ ) ,
278+ & timestamp. to_le_bytes ( ) ,
279+ )
280+ . await ;
281+ let st = rand:: thread_rng ( ) . gen_range ( 32 ..64 ) ;
282+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_secs ( st) ) . await ;
283+ }
284+ } ) ;
285+ } ) ;
286+ } else {
287+ return Err ( "Cannot find instance_id while heartbeat is enabled, please specify instance_id to enable this functionality." . into ( ) ) ;
288+ }
289+ }
290+ if args. keep_alive_when_disconnect {
254291 for thread in threads {
255292 thread. join ( ) . unwrap ( ) ;
256293 }
@@ -282,9 +319,9 @@ pub fn _protocol_start(
282319 Ok ( ( ) )
283320}
284321
285- #[ derive( Debug , Parser ) ]
322+ #[ derive( Debug , Clone , Default , Parser ) ]
286323#[ command( name = "CoLink-SDK" , about = "CoLink-SDK" ) ]
287- pub struct CommandLineArgs {
324+ pub struct CoLinkProtocolCommandLineArgs {
288325 /// Address of CoLink server
289326 #[ arg( short, long, env = "COLINK_CORE_ADDR" ) ]
290327 pub addr : String ,
@@ -293,6 +330,10 @@ pub struct CommandLineArgs {
293330 #[ arg( short, long, env = "COLINK_JWT" ) ]
294331 pub jwt : String ,
295332
333+ /// Path to CA certificate.
334+ #[ arg( long, env = "COLINK_INSTANCE_ID" ) ]
335+ pub instance_id : Option < String > ,
336+
296337 /// Path to CA certificate.
297338 #[ arg( long, env = "COLINK_CA_CERT" ) ]
298339 pub ca : Option < String > ,
@@ -309,37 +350,34 @@ pub struct CommandLineArgs {
309350 #[ arg( long, env = "COLINK_KEEP_ALIVE_WHEN_DISCONNECT" ) ]
310351 pub keep_alive_when_disconnect : bool ,
311352
353+ /// Enable heartbeat.
354+ #[ arg( long, env = "COLINK_ENABLE_HEARTBEAT" ) ]
355+ pub enable_heartbeat : bool ,
356+
312357 /// Public address for the variable transfer inbox.
313358 #[ arg( long, env = "COLINK_VT_PUBLIC_ADDR" ) ]
314359 pub vt_public_addr : Option < String > ,
315360}
316361
317- pub fn _colink_parse_args ( ) -> ( CoLink , bool , Option < String > ) {
362+ pub fn _colink_parse_args ( ) -> ( CoLink , CoLinkProtocolCommandLineArgs ) {
318363 tracing_subscriber:: fmt:: init ( ) ;
319- let CommandLineArgs {
320- addr,
321- jwt,
322- ca,
323- cert,
324- key,
325- keep_alive_when_disconnect,
326- vt_public_addr,
327- } = CommandLineArgs :: parse ( ) ;
328- let mut cl = CoLink :: new ( & addr, & jwt) ;
329- if let Some ( ca) = ca {
364+ let args = CoLinkProtocolCommandLineArgs :: parse ( ) ;
365+ let args_clone = args. clone ( ) ;
366+ let mut cl = CoLink :: new ( & args. addr , & args. jwt ) ;
367+ if let Some ( ca) = args. ca {
330368 cl = cl. ca_certificate ( & ca) ;
331369 }
332- if let ( Some ( cert) , Some ( key) ) = ( cert, key) {
370+ if let ( Some ( cert) , Some ( key) ) = ( args . cert , args . key ) {
333371 cl = cl. identity ( & cert, & key) ;
334372 }
335- ( cl, keep_alive_when_disconnect , vt_public_addr )
373+ ( cl, args_clone )
336374}
337375
338376#[ macro_export]
339377macro_rules! protocol_start {
340378 ( $( $x: expr ) ,* ) => {
341379 fn main( ) -> Result <( ) , Box <dyn std:: error:: Error + Send + Sync + ' static >> {
342- let ( cl, keep_alive_when_disconnect , vt_public_addr ) = colink:: _colink_parse_args( ) ;
380+ let ( cl, args ) = colink:: _colink_parse_args( ) ;
343381
344382 let mut user_funcs: std:: collections:: HashMap <
345383 String ,
@@ -349,7 +387,7 @@ macro_rules! protocol_start {
349387 user_funcs. insert( $x. 0 . to_string( ) , Box :: new( $x. 1 ) ) ;
350388 ) *
351389
352- colink:: _protocol_start( cl, user_funcs, keep_alive_when_disconnect , vt_public_addr ) ?;
390+ colink:: _protocol_start( cl, user_funcs, args ) ?;
353391
354392 Ok ( ( ) )
355393 }
@@ -368,8 +406,12 @@ macro_rules! protocol_attach {
368406 $(
369407 user_funcs. insert( $x. 0 . to_string( ) , Box :: new( $x. 1 ) ) ;
370408 ) *
409+ let args = colink:: CoLinkProtocolCommandLineArgs {
410+ vt_public_addr: Some ( "127.0.0.1" . to_string( ) ) ,
411+ ..Default :: default ( )
412+ } ;
371413 std:: thread:: spawn( || {
372- colink:: _protocol_start( cl, user_funcs, false , Some ( "127.0.0.1" . to_string ( ) ) ) ?;
414+ colink:: _protocol_start( cl, user_funcs, args ) ?;
373415 Ok :: <( ) , Box <dyn std:: error:: Error + Send + Sync + ' static >>( ( ) )
374416 } ) ;
375417 }
0 commit comments