1- use std:: collections:: { BinaryHeap , HashMap } ;
1+ use std:: collections:: { BTreeMap , BinaryHeap , HashMap } ;
22use std:: sync:: Arc ;
33use std:: time:: Duration ;
44
55use rostra_client_db:: { Database , IdsFolloweesRecord , InsertEventOutcome } ;
6+ use rostra_core:: ShortEventId ;
67use rostra_core:: event:: PersonaId ;
78use rostra_core:: id:: RostraId ;
8- use rostra_core :: ShortEventId ;
9+ use rostra_p2p :: Connection ;
910use rostra_p2p:: connection:: GetHeadRequest ;
1011use rostra_util:: is_rostra_dev_mode_set;
1112use rostra_util_error:: { BoxedErrorResult , FmtCompact , WhateverResult } ;
@@ -14,8 +15,9 @@ use snafu::ResultExt as _;
1415use tokio:: sync:: watch;
1516use tracing:: { debug, info, instrument, trace} ;
1617
17- use crate :: client :: Client ;
18+ use super :: connection_cache :: ConnectionCache ;
1819use crate :: ClientRef ;
20+ use crate :: client:: Client ;
1921const LOG_TARGET : & str = "rostra::head_checker" ;
2022
2123pub struct FolloweeHeadChecker {
@@ -33,7 +35,6 @@ impl FolloweeHeadChecker {
3335 client : client. handle ( ) ,
3436 db : client. db ( ) . to_owned ( ) ,
3537 self_id : client. rostra_id ( ) ,
36-
3738 followee_updated : client. self_followees_subscribe ( ) ,
3839 check_for_updates_rx : client. check_for_updates_tx_subscribe ( ) ,
3940 }
@@ -70,6 +71,9 @@ impl FolloweeHeadChecker {
7071 break ;
7172 } ;
7273
74+ let mut connections = ConnectionCache :: new ( ) ;
75+ let mut followers_by_followee = BTreeMap :: new ( ) ;
76+
7377 let self_followees = storage. get_self_followees ( ) . await ;
7478
7579 for ( followee, _persona_id) in [ & ( self . self_id , PersonaId :: default ( ) ) ]
@@ -98,9 +102,16 @@ impl FolloweeHeadChecker {
98102 }
99103 Ok ( Some ( head) ) => {
100104 info ! ( target: LOG_TARGET , id = %followee, %source, "Has updates" ) ;
101- if let Err ( err) = self . download_new_data ( & client, * followee, head) . await
105+ if let Err ( err) = self
106+ . download_new_data (
107+ * followee,
108+ head,
109+ & mut connections,
110+ & mut followers_by_followee,
111+ )
112+ . await
102113 {
103- info ! ( target: LOG_TARGET , err = %err. fmt_compact( ) , id = %followee, "Failed to download new data" ) ;
114+ info ! ( target: LOG_TARGET , err = %( & * err) . fmt_compact( ) , id = %followee, "Failed to download new data" ) ;
104115 }
105116 }
106117 }
@@ -147,20 +158,73 @@ impl FolloweeHeadChecker {
147158 }
148159
149160 async fn download_new_data (
161+ & self ,
162+ rostra_id : RostraId ,
163+ head : ShortEventId ,
164+ connections : & mut ConnectionCache ,
165+ followers_by_followee : & mut BTreeMap < RostraId , Vec < RostraId > > ,
166+ ) -> BoxedErrorResult < ( ) > {
167+ let followers = if let Some ( followers) = followers_by_followee. get ( & rostra_id) {
168+ followers
169+ } else {
170+ let client = self . client . client_ref ( ) . boxed ( ) ?;
171+ let storage = client. db ( ) ;
172+ let followers = storage. get_followers ( rostra_id) . await ;
173+ followers_by_followee. insert ( rostra_id, followers) ;
174+
175+ followers_by_followee
176+ . get ( & rostra_id)
177+ . expect ( "Just inserted" )
178+ } ;
179+
180+ for follower_id in followers. iter ( ) . chain ( [ rostra_id, self . self_id ] . iter ( ) ) {
181+ let Ok ( client) = self . client . client_ref ( ) . boxed ( ) else {
182+ break ;
183+ } ;
184+ let Some ( conn) = connections. get_or_connect ( & client, * follower_id) . await else {
185+ continue ;
186+ } ;
187+
188+ debug ! ( target: LOG_TARGET ,
189+ rostra_id = %rostra_id,
190+ head = %head,
191+ follower_id = %follower_id,
192+ "Getting event data from a peer"
193+ ) ;
194+
195+ match self
196+ . download_new_data_from ( & client, rostra_id, conn, head)
197+ . await
198+ {
199+ Ok ( true ) => {
200+ return Ok ( ( ) ) ;
201+ }
202+ Ok ( false ) => { }
203+ Err ( err) => {
204+ debug ! ( target: LOG_TARGET ,
205+ rostra_id = %rostra_id,
206+ head = %head,
207+ follower_id = %follower_id,
208+ err = %err. fmt_compact( ) ,
209+ "Error getting event from a peer"
210+ ) ;
211+ }
212+ }
213+ }
214+ Ok ( ( ) )
215+ }
216+ async fn download_new_data_from (
150217 & self ,
151218 client : & ClientRef < ' _ > ,
152219 rostra_id : RostraId ,
220+ conn : & mut Connection ,
153221 head : ShortEventId ,
154- ) -> WhateverResult < ( ) > {
222+ ) -> WhateverResult < bool > {
155223 let mut events = BinaryHeap :: from ( [ ( 0 , head) ] ) ;
224+ let mut downloaded_anything = false ;
156225
157226 let storage = client. db ( ) ;
158227
159- let conn = client
160- . connect ( rostra_id)
161- . await
162- . whatever_context ( "Failed to connect" ) ?;
163-
164228 let peer_id = conn. remote_node_id ( ) ;
165229
166230 while let Some ( ( depth, event_id) ) = events. pop ( ) {
@@ -187,6 +251,7 @@ impl FolloweeHeadChecker {
187251 ) ;
188252 continue ;
189253 } ;
254+ downloaded_anything = true ;
190255 let ( insert_outcome, process_state) = storage. process_event ( & event) . await ;
191256
192257 if let InsertEventOutcome :: Inserted {
@@ -226,6 +291,6 @@ impl FolloweeHeadChecker {
226291 }
227292 }
228293
229- Ok ( ( ) )
294+ Ok ( downloaded_anything )
230295 }
231296}
0 commit comments