@@ -27,19 +27,18 @@ use quic_rpc::{
27
27
RpcServer , ServiceEndpoint ,
28
28
} ;
29
29
use serde:: { Deserialize , Serialize } ;
30
- use tokio:: sync:: mpsc;
31
30
use tokio_util:: { sync:: CancellationToken , task:: LocalPoolHandle } ;
32
31
use tracing:: { debug, error, error_span, info, trace, warn, Instrument } ;
33
32
34
33
use crate :: {
35
34
client:: RPC_ALPN ,
36
35
docs_engine:: Engine ,
37
- node:: { Event , NodeInner } ,
36
+ node:: NodeInner ,
38
37
rpc_protocol:: { Request , Response , RpcService } ,
39
38
util:: { fs:: load_secret_key, path:: IrohPaths } ,
40
39
} ;
41
40
42
- use super :: { rpc, rpc_status:: RpcStatus , Callbacks , EventCallback , Node } ;
41
+ use super :: { rpc, rpc_status:: RpcStatus , Node } ;
43
42
44
43
pub const PROTOCOLS : [ & [ u8 ] ; 3 ] = [ iroh_blobs:: protocol:: ALPN , GOSSIP_ALPN , DOCS_ALPN ] ;
45
44
@@ -69,7 +68,7 @@ const MAX_STREAMS: u64 = 10;
69
68
///
70
69
/// The returned [`Node`] is awaitable to know when it finishes. It can be terminated
71
70
/// using [`Node::shutdown`].
72
- #[ derive( Debug ) ]
71
+ #[ derive( derive_more :: Debug ) ]
73
72
pub struct Builder < D , E = DummyServerEndpoint >
74
73
where
75
74
D : Map ,
88
87
docs_store : iroh_docs:: store:: fs:: Store ,
89
88
#[ cfg( any( test, feature = "test-utils" ) ) ]
90
89
insecure_skip_relay_cert_verify : bool ,
90
+ /// Callback to register when a gc loop is done
91
+ #[ debug( "callback" ) ]
92
+ gc_done_callback : Option < Box < dyn Fn ( ) + Send > > ,
91
93
}
92
94
93
95
/// Configuration for storage.
@@ -135,6 +137,7 @@ impl Default for Builder<iroh_blobs::store::mem::Store> {
135
137
node_discovery : Default :: default ( ) ,
136
138
#[ cfg( any( test, feature = "test-utils" ) ) ]
137
139
insecure_skip_relay_cert_verify : false ,
140
+ gc_done_callback : None ,
138
141
}
139
142
}
140
143
}
@@ -160,6 +163,7 @@ impl<D: Map> Builder<D> {
160
163
node_discovery : Default :: default ( ) ,
161
164
#[ cfg( any( test, feature = "test-utils" ) ) ]
162
165
insecure_skip_relay_cert_verify : false ,
166
+ gc_done_callback : None ,
163
167
}
164
168
}
165
169
}
@@ -222,6 +226,7 @@ where
222
226
node_discovery : self . node_discovery ,
223
227
#[ cfg( any( test, feature = "test-utils" ) ) ]
224
228
insecure_skip_relay_cert_verify : false ,
229
+ gc_done_callback : self . gc_done_callback ,
225
230
} )
226
231
}
227
232
@@ -242,6 +247,7 @@ where
242
247
node_discovery : self . node_discovery ,
243
248
#[ cfg( any( test, feature = "test-utils" ) ) ]
244
249
insecure_skip_relay_cert_verify : self . insecure_skip_relay_cert_verify ,
250
+ gc_done_callback : self . gc_done_callback ,
245
251
}
246
252
}
247
253
@@ -267,6 +273,7 @@ where
267
273
node_discovery : self . node_discovery ,
268
274
#[ cfg( any( test, feature = "test-utils" ) ) ]
269
275
insecure_skip_relay_cert_verify : self . insecure_skip_relay_cert_verify ,
276
+ gc_done_callback : self . gc_done_callback ,
270
277
} )
271
278
}
272
279
@@ -337,6 +344,13 @@ where
337
344
self
338
345
}
339
346
347
+ /// Register a callback for when GC is done.
348
+ #[ cfg( any( test, feature = "test-utils" ) ) ]
349
+ pub fn register_gc_done_cb ( mut self , cb : Box < dyn Fn ( ) + Send > ) -> Self {
350
+ self . gc_done_callback . replace ( cb) ;
351
+ self
352
+ }
353
+
340
354
/// Whether to log the SSL pre-master key.
341
355
///
342
356
/// If `true` and the `SSLKEYLOGFILE` environment variable is the path to a file this
@@ -352,7 +366,7 @@ where
352
366
/// This will create the underlying network server and spawn a tokio task accepting
353
367
/// connections. The returned [`Node`] can be used to control the task as well as
354
368
/// get information about it.
355
- pub async fn spawn ( self ) -> Result < Node < D > > {
369
+ pub async fn spawn ( mut self ) -> Result < Node < D > > {
356
370
trace ! ( "spawning node" ) ;
357
371
let lp = LocalPoolHandle :: new ( num_cpus:: get ( ) ) ;
358
372
@@ -406,7 +420,6 @@ where
406
420
let endpoint = endpoint. bind ( bind_port) . await ?;
407
421
trace ! ( "created quinn endpoint" ) ;
408
422
409
- let ( cb_sender, cb_receiver) = mpsc:: channel ( 8 ) ;
410
423
let cancel_token = CancellationToken :: new ( ) ;
411
424
412
425
debug ! ( "rpc listening on: {:?}" , self . rpc_endpoint. local_addr( ) ) ;
@@ -427,12 +440,13 @@ where
427
440
) ;
428
441
let sync_db = sync. sync . clone ( ) ;
429
442
430
- let callbacks = Callbacks :: default ( ) ;
431
443
let gc_task = if let GcPolicy :: Interval ( gc_period) = self . gc_policy {
432
444
tracing:: info!( "Starting GC task with interval {:?}" , gc_period) ;
433
445
let db = self . blobs_store . clone ( ) ;
434
- let callbacks = callbacks. clone ( ) ;
435
- let task = lp. spawn_pinned ( move || Self :: gc_loop ( db, sync_db, gc_period, callbacks) ) ;
446
+ let gc_done_callback = self . gc_done_callback . take ( ) ;
447
+
448
+ let task =
449
+ lp. spawn_pinned ( move || Self :: gc_loop ( db, sync_db, gc_period, gc_done_callback) ) ;
436
450
Some ( task. into ( ) )
437
451
} else {
438
452
None
@@ -446,8 +460,6 @@ where
446
460
secret_key : self . secret_key ,
447
461
controller,
448
462
cancel_token,
449
- callbacks : callbacks. clone ( ) ,
450
- cb_sender,
451
463
gc_task,
452
464
rt : lp. clone ( ) ,
453
465
sync,
@@ -464,8 +476,6 @@ where
464
476
async move {
465
477
Self :: run (
466
478
ep,
467
- callbacks,
468
- cb_receiver,
469
479
handler,
470
480
self . rpc_endpoint ,
471
481
internal_rpc,
@@ -508,8 +518,6 @@ where
508
518
#[ allow( clippy:: too_many_arguments) ]
509
519
async fn run (
510
520
server : Endpoint ,
511
- callbacks : Callbacks ,
512
- mut cb_receiver : mpsc:: Receiver < EventCallback > ,
513
521
handler : rpc:: Handler < D > ,
514
522
rpc : E ,
515
523
internal_rpc : impl ServiceEndpoint < RpcService > ,
@@ -586,10 +594,6 @@ where
586
594
}
587
595
} ) ;
588
596
} ,
589
- // Handle new callbacks
590
- Some ( cb) = cb_receiver. recv( ) => {
591
- callbacks. push( cb) . await ;
592
- }
593
597
else => break ,
594
598
}
595
599
}
@@ -609,7 +613,7 @@ where
609
613
db : D ,
610
614
ds : iroh_docs:: actor:: SyncHandle ,
611
615
gc_period : Duration ,
612
- callbacks : Callbacks ,
616
+ done_cb : Option < Box < dyn Fn ( ) + Send > > ,
613
617
) {
614
618
let mut live = BTreeSet :: new ( ) ;
615
619
tracing:: debug!( "GC loop starting {:?}" , gc_period) ;
@@ -623,14 +627,11 @@ where
623
627
// do delay before the two phases of GC
624
628
tokio:: time:: sleep ( gc_period) . await ;
625
629
tracing:: debug!( "Starting GC" ) ;
626
- callbacks
627
- . send ( Event :: Db ( iroh_blobs:: store:: Event :: GcStarted ) )
628
- . await ;
629
630
live. clear ( ) ;
630
631
let doc_hashes = match ds. content_hashes ( ) . await {
631
632
Ok ( hashes) => hashes,
632
633
Err ( err) => {
633
- tracing:: error !( "Error getting doc hashes: {}" , err) ;
634
+ tracing:: warn !( "Error getting doc hashes: {}" , err) ;
634
635
continue ' outer;
635
636
}
636
637
} ;
@@ -680,9 +681,9 @@ where
680
681
}
681
682
}
682
683
}
683
- callbacks
684
- . send ( Event :: Db ( iroh_blobs :: store :: Event :: GcCompleted ) )
685
- . await ;
684
+ if let Some ( ref cb ) = done_cb {
685
+ cb ( ) ;
686
+ }
686
687
}
687
688
}
688
689
}
@@ -719,7 +720,7 @@ async fn handle_connection<D: BaoStore>(
719
720
iroh_blobs:: provider:: handle_connection (
720
721
connection,
721
722
node. db . clone ( ) ,
722
- node . callbacks . clone ( ) ,
723
+ MockEventSender ,
723
724
node. rt . clone ( ) ,
724
725
)
725
726
. await
@@ -776,3 +777,12 @@ fn make_rpc_endpoint(
776
777
777
778
Ok ( ( rpc_endpoint, actual_rpc_port) )
778
779
}
780
+
781
+ #[ derive( Debug , Clone ) ]
782
+ struct MockEventSender ;
783
+
784
+ impl iroh_blobs:: provider:: EventSender for MockEventSender {
785
+ fn send ( & self , _event : iroh_blobs:: provider:: Event ) -> futures_lite:: future:: Boxed < ( ) > {
786
+ Box :: pin ( std:: future:: ready ( ( ) ) )
787
+ }
788
+ }
0 commit comments