@@ -25,21 +25,21 @@ pub struct CoLinkProtocol {
25
25
protocol_and_role : String ,
26
26
cl : CoLink ,
27
27
user_func : Box < dyn ProtocolEntry > ,
28
- vt_public_addr : Option < String > ,
28
+ args : CoLinkProtocolCommandLineArgs ,
29
29
}
30
30
31
31
impl CoLinkProtocol {
32
32
pub fn new (
33
33
protocol_and_role : & str ,
34
34
cl : CoLink ,
35
35
user_func : Box < dyn ProtocolEntry > ,
36
- vt_public_addr : Option < String > ,
36
+ args : CoLinkProtocolCommandLineArgs ,
37
37
) -> Self {
38
38
Self {
39
39
protocol_and_role : protocol_and_role. to_string ( ) ,
40
40
cl,
41
41
user_func,
42
- vt_public_addr ,
42
+ args ,
43
43
}
44
44
}
45
45
@@ -78,11 +78,20 @@ impl CoLinkProtocol {
78
78
{
79
79
cl. vt_p2p_ctx =
80
80
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 ( ) ,
82
82
..Default :: default ( )
83
83
} ) ;
84
84
}
85
85
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 ?;
86
95
match self
87
96
. user_func
88
97
. start ( cl, task. protocol_param , task. participants )
@@ -170,8 +179,7 @@ impl CoLinkProtocol {
170
179
pub fn _protocol_start (
171
180
cl : CoLink ,
172
181
user_funcs : HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > ,
173
- keep_alive_when_disconnect : bool ,
174
- vt_public_addr : Option < String > ,
182
+ args : CoLinkProtocolCommandLineArgs ,
175
183
) -> Result < ( ) , Error > {
176
184
let mut operator_funcs: HashMap < String , Box < dyn ProtocolEntry + Send + Sync > > = HashMap :: new ( ) ;
177
185
let mut protocols = HashSet :: new ( ) ;
@@ -233,14 +241,14 @@ pub fn _protocol_start(
233
241
let mut threads = vec ! [ ] ;
234
242
for ( protocol_and_role, user_func) in operator_funcs {
235
243
let cl = cl. clone ( ) ;
236
- let vt_public_addr = vt_public_addr . clone ( ) ;
244
+ let args = args . clone ( ) ;
237
245
threads. push ( thread:: spawn ( || {
238
246
tokio:: runtime:: Builder :: new_multi_thread ( )
239
247
. enable_all ( )
240
248
. build ( )
241
249
. unwrap ( )
242
250
. 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 )
244
252
. start ( )
245
253
. await
246
254
{
@@ -250,7 +258,36 @@ pub fn _protocol_start(
250
258
} ) ;
251
259
} ) ) ;
252
260
}
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 {
254
291
for thread in threads {
255
292
thread. join ( ) . unwrap ( ) ;
256
293
}
@@ -282,9 +319,9 @@ pub fn _protocol_start(
282
319
Ok ( ( ) )
283
320
}
284
321
285
- #[ derive( Debug , Parser ) ]
322
+ #[ derive( Debug , Clone , Default , Parser ) ]
286
323
#[ command( name = "CoLink-SDK" , about = "CoLink-SDK" ) ]
287
- pub struct CommandLineArgs {
324
+ pub struct CoLinkProtocolCommandLineArgs {
288
325
/// Address of CoLink server
289
326
#[ arg( short, long, env = "COLINK_CORE_ADDR" ) ]
290
327
pub addr : String ,
@@ -293,6 +330,10 @@ pub struct CommandLineArgs {
293
330
#[ arg( short, long, env = "COLINK_JWT" ) ]
294
331
pub jwt : String ,
295
332
333
+ /// Path to CA certificate.
334
+ #[ arg( long, env = "COLINK_INSTANCE_ID" ) ]
335
+ pub instance_id : Option < String > ,
336
+
296
337
/// Path to CA certificate.
297
338
#[ arg( long, env = "COLINK_CA_CERT" ) ]
298
339
pub ca : Option < String > ,
@@ -309,37 +350,34 @@ pub struct CommandLineArgs {
309
350
#[ arg( long, env = "COLINK_KEEP_ALIVE_WHEN_DISCONNECT" ) ]
310
351
pub keep_alive_when_disconnect : bool ,
311
352
353
+ /// Enable heartbeat.
354
+ #[ arg( long, env = "COLINK_ENABLE_HEARTBEAT" ) ]
355
+ pub enable_heartbeat : bool ,
356
+
312
357
/// Public address for the variable transfer inbox.
313
358
#[ arg( long, env = "COLINK_VT_PUBLIC_ADDR" ) ]
314
359
pub vt_public_addr : Option < String > ,
315
360
}
316
361
317
- pub fn _colink_parse_args ( ) -> ( CoLink , bool , Option < String > ) {
362
+ pub fn _colink_parse_args ( ) -> ( CoLink , CoLinkProtocolCommandLineArgs ) {
318
363
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 {
330
368
cl = cl. ca_certificate ( & ca) ;
331
369
}
332
- if let ( Some ( cert) , Some ( key) ) = ( cert, key) {
370
+ if let ( Some ( cert) , Some ( key) ) = ( args . cert , args . key ) {
333
371
cl = cl. identity ( & cert, & key) ;
334
372
}
335
- ( cl, keep_alive_when_disconnect , vt_public_addr )
373
+ ( cl, args_clone )
336
374
}
337
375
338
376
#[ macro_export]
339
377
macro_rules! protocol_start {
340
378
( $( $x: expr ) ,* ) => {
341
379
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( ) ;
343
381
344
382
let mut user_funcs: std:: collections:: HashMap <
345
383
String ,
@@ -349,7 +387,7 @@ macro_rules! protocol_start {
349
387
user_funcs. insert( $x. 0 . to_string( ) , Box :: new( $x. 1 ) ) ;
350
388
) *
351
389
352
- colink:: _protocol_start( cl, user_funcs, keep_alive_when_disconnect , vt_public_addr ) ?;
390
+ colink:: _protocol_start( cl, user_funcs, args ) ?;
353
391
354
392
Ok ( ( ) )
355
393
}
@@ -368,8 +406,12 @@ macro_rules! protocol_attach {
368
406
$(
369
407
user_funcs. insert( $x. 0 . to_string( ) , Box :: new( $x. 1 ) ) ;
370
408
) *
409
+ let args = colink:: CoLinkProtocolCommandLineArgs {
410
+ vt_public_addr: Some ( "127.0.0.1" . to_string( ) ) ,
411
+ ..Default :: default ( )
412
+ } ;
371
413
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 ) ?;
373
415
Ok :: <( ) , Box <dyn std:: error:: Error + Send + Sync + ' static >>( ( ) )
374
416
} ) ;
375
417
}
0 commit comments