@@ -16,14 +16,30 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
1616use crate :: domolibp2p:: { self , generate_rsa_key} ;
1717use crate :: {
1818 cache:: local:: DomoCacheStateMessage ,
19- data:: DomoEvent ,
20- dht:: { dht_channel, Command , Event } ,
19+ dht:: { dht_channel, Command , Event as DhtEvent } ,
2120 domolibp2p:: DomoBehaviour ,
2221 utils, Error ,
2322} ;
2423
2524use self :: local:: { DomoCacheElement , LocalCache , Query } ;
2625
26+ /// DHT state change
27+ #[ derive( Debug ) ]
28+ pub enum Event {
29+ /// Persistent, structured data
30+ ///
31+ /// The information is persisted across nodes.
32+ /// Newly joining nodes will receive it from other participants and
33+ /// the local cache can be queried for it.
34+ PersistentData ( DomoCacheElement ) ,
35+ /// Volatile, unstructured data
36+ ///
37+ /// The information is transmitted across all the nodes participating
38+ VolatileData ( Value ) ,
39+ /// Notify the peer availability
40+ ReadyPeers ( Vec < String > ) ,
41+ }
42+
2743/// Builder for a Cached DHT Node
2844// TODO: make it Clone
2945pub struct Builder {
@@ -37,9 +53,7 @@ impl Builder {
3753 }
3854
3955 /// Instantiate a new DHT node a return
40- pub async fn make_channel (
41- self ,
42- ) -> Result < ( Cache , impl Stream < Item = DomoEvent > ) , crate :: Error > {
56+ pub async fn make_channel ( self ) -> Result < ( Cache , impl Stream < Item = Event > ) , crate :: Error > {
4357 let loopback_only = self . cfg . loopback ;
4458 let shared_key = domolibp2p:: parse_hex_key ( & self . cfg . shared_key ) ?;
4559 let private_key_file = self . cfg . private_key . as_ref ( ) ;
@@ -239,7 +253,7 @@ pub fn cache_channel(
239253 local : LocalCache ,
240254 swarm : Swarm < DomoBehaviour > ,
241255 resend_interval : u64 ,
242- ) -> ( Cache , impl Stream < Item = DomoEvent > ) {
256+ ) -> ( Cache , impl Stream < Item = Event > ) {
243257 let local_peer_id = swarm. local_peer_id ( ) . to_string ( ) ;
244258
245259 let ( cmd, r, _j) = dht_channel ( swarm) ;
@@ -289,7 +303,7 @@ pub fn cache_channel(
289303 let cmd = cmd. clone ( ) ;
290304 async move {
291305 match ev {
292- Event :: Config ( cfg) => {
306+ DhtEvent :: Config ( cfg) => {
293307 let m: DomoCacheStateMessage = serde_json:: from_str ( & cfg) . unwrap ( ) ;
294308
295309 let hash = local_write. get_hash ( ) . await ;
@@ -338,16 +352,16 @@ pub fn cache_channel(
338352
339353 None
340354 }
341- Event :: Discovered ( who ) => Some ( DomoEvent :: NewPeers (
355+ DhtEvent :: Discovered ( _who ) => None /* Some(DomoEvent::NewPeers(
342356 who.into_iter().map(|w| w.to_string()).collect(),
343- ) ) ,
344- Event :: VolatileData ( data) => {
357+ ))*/ ,
358+ DhtEvent :: VolatileData ( data) => {
345359 // TODO we swallow errors quietly here
346360 serde_json:: from_str ( & data)
347361 . ok ( )
348- . map ( DomoEvent :: VolatileData )
362+ . map ( Event :: VolatileData )
349363 }
350- Event :: PersistentData ( data) => {
364+ DhtEvent :: PersistentData ( data) => {
351365 if let Ok ( mut elem) = serde_json:: from_str :: < DomoCacheElement > ( & data) {
352366 if elem. republication_timestamp != 0 {
353367 log:: debug!( "Retransmission" ) ;
@@ -358,7 +372,15 @@ pub fn cache_channel(
358372 . try_put ( & elem)
359373 . await
360374 . ok ( )
361- . map ( |_| DomoEvent :: PersistentData ( elem) )
375+ . map ( |_| Event :: PersistentData ( elem) )
376+ } else {
377+ None
378+ }
379+ }
380+ DhtEvent :: Ready ( peers) => {
381+ if !peers. is_empty ( ) {
382+ Some ( Event :: ReadyPeers (
383+ peers. into_iter ( ) . map ( |p| p. to_string ( ) ) . collect ( ) ) )
362384 } else {
363385 None
364386 }
@@ -416,38 +438,52 @@ mod test {
416438 expected_peers. insert ( b_c. peer_id . clone ( ) ) ;
417439 expected_peers. insert ( c_c. peer_id . clone ( ) ) ;
418440
419- tokio:: task:: spawn ( async move {
420- let a_ev = pin ! ( a_ev) ;
421- let b_ev = pin ! ( b_ev) ;
422- let c_ev = pin ! ( c_ev) ;
423- for uuid in 0 ..10 {
424- let _ = a_c
425- . put (
426- "Topic" ,
427- & format ! ( "uuid-{uuid}" ) ,
428- serde_json:: json!( { "key" : uuid} ) ,
429- )
430- . await ;
441+ let mut a_ev = pin ! ( a_ev) ;
442+ let b_ev = pin ! ( b_ev) ;
443+ let c_ev = pin ! ( c_ev) ;
444+
445+ while let Some ( ev) = a_ev. next ( ) . await {
446+ match ev {
447+ Event :: ReadyPeers ( peers) => {
448+ log:: info!( "Ready peers {peers:?}" ) ;
449+ break ;
450+ }
451+ _ => log:: debug!( "waiting for ready {ev:?}" ) ,
431452 }
453+ }
432454
433- let mut s = (
434- a_ev. map ( |ev| ( "a" , ev) ) ,
435- b_ev. map ( |ev| ( "b" , ev) ) ,
436- c_ev. map ( |ev| ( "c" , ev) ) ,
437- )
438- . merge ( ) ;
439-
440- while let Some ( ( node, ev) ) = s. next ( ) . await {
441- match ev {
442- DomoEvent :: PersistentData ( data) => {
443- log:: debug!( "{node}: Got data {data:?}" ) ;
444- }
445- _ => {
446- log:: debug!( "{node}: Other {ev:?}" ) ;
455+ for uuid in 0 ..10 {
456+ let _ = a_c
457+ . put (
458+ "Topic" ,
459+ & format ! ( "uuid-{uuid}" ) ,
460+ serde_json:: json!( { "key" : uuid} ) ,
461+ )
462+ . await ;
463+ }
464+ let mut s = (
465+ a_ev. map ( |ev| ( "a" , ev) ) ,
466+ b_ev. map ( |ev| ( "b" , ev) ) ,
467+ c_ev. map ( |ev| ( "c" , ev) ) ,
468+ )
469+ . merge ( ) ;
470+
471+ // wait for the nodes to have at least some elements
472+ let mut seen = 0 ;
473+ while let Some ( ( node, ev) ) = s. next ( ) . await {
474+ match ev {
475+ Event :: PersistentData ( data) => {
476+ log:: debug!( "{node}: Got data {data:?}" ) ;
477+ seen += 1 ;
478+ if seen > 10 {
479+ break ;
447480 }
448481 }
482+ _ => {
483+ log:: debug!( "{node}: Other {ev:?}" ) ;
484+ }
449485 }
450- } ) ;
486+ }
451487
452488 log:: info!( "Adding D" ) ;
453489
@@ -457,7 +493,7 @@ mod test {
457493 while !expected. is_empty ( ) {
458494 let ev = d_ev. next ( ) . await . unwrap ( ) ;
459495 match ev {
460- DomoEvent :: PersistentData ( data) => {
496+ Event :: PersistentData ( data) => {
461497 assert ! ( expected. remove( & data. topic_uuid) ) ;
462498 log:: warn!( "d: Got data {data:?}" ) ;
463499 }
0 commit comments