@@ -6,7 +6,7 @@ use pangea_client::{
66 futures:: StreamExt , provider:: FuelProvider , query:: Bound , requests:: fuel:: GetSparkOrderRequest ,
77 ClientBuilder , Format , WsProvider ,
88} ;
9- use tokio:: time:: sleep;
9+ use tokio:: time:: { interval , sleep} ;
1010use std:: collections:: HashSet ;
1111use std:: str:: FromStr ;
1212use std:: sync:: Arc ;
@@ -16,14 +16,16 @@ use crate::config::env::ev;
1616use crate :: error:: Error ;
1717use crate :: indexer:: order_event_handler:: handle_order_event;
1818use crate :: indexer:: order_event_handler:: PangeaOrderEvent ;
19+ use crate :: storage:: matching_orders:: MatchingOrders ;
1920use crate :: storage:: order_book:: OrderBook ;
2021
2122pub async fn initialize_pangea_indexer (
2223 tasks : & mut Vec < tokio:: task:: JoinHandle < ( ) > > ,
2324 order_book : Arc < OrderBook > ,
25+ matching_orders : Arc < MatchingOrders > ,
2426) -> Result < ( ) , Error > {
2527 let ws_task_pangea = tokio:: spawn ( async move {
26- if let Err ( e) = start_pangea_indexer ( order_book) . await {
28+ if let Err ( e) = start_pangea_indexer ( order_book, matching_orders ) . await {
2729 eprintln ! ( "Pangea error: {}" , e) ;
2830 }
2931 } ) ;
@@ -32,22 +34,24 @@ pub async fn initialize_pangea_indexer(
3234 Ok ( ( ) )
3335}
3436
35- async fn start_pangea_indexer ( order_book : Arc < OrderBook > ) -> Result < ( ) , Error > {
37+ async fn start_pangea_indexer ( order_book : Arc < OrderBook > , matching_orders : Arc < MatchingOrders > ) -> Result < ( ) , Error > {
3638 let client = create_pangea_client ( ) . await ?;
3739
3840 let contract_start_block: i64 = ev ( "CONTRACT_START_BLOCK" ) ?. parse ( ) ?;
3941 let contract_h256 = H256 :: from_str ( & ev ( "CONTRACT_ID" ) ?) ?;
4042
4143 let mut last_processed_block =
42- fetch_historical_data ( & client, & order_book, contract_start_block, contract_h256) . await ?;
44+ fetch_historical_data ( & client, & order_book, & matching_orders,
45+ contract_start_block, contract_h256) . await ?;
4346
4447 if last_processed_block == 0 {
4548 last_processed_block = contract_start_block;
4649 }
4750
4851 info ! ( "Switching to listening for new orders (deltas)" ) ;
4952
50- listen_for_new_deltas ( & client, & order_book, last_processed_block, contract_h256) . await
53+ listen_for_new_deltas ( & client, & order_book, & matching_orders,
54+ last_processed_block, contract_h256) . await
5155}
5256
5357async fn create_pangea_client ( ) -> Result < Client < WsProvider > , Error > {
@@ -79,6 +83,7 @@ async fn get_latest_block(chain_id: ChainId) -> Result<i64, Error> {
7983async fn fetch_historical_data (
8084 client : & Client < WsProvider > ,
8185 order_book : & Arc < OrderBook > ,
86+ matching_orders : & Arc < MatchingOrders > ,
8287 contract_start_block : i64 ,
8388 contract_h256 : H256 ,
8489) -> Result < i64 , Error > {
@@ -115,7 +120,8 @@ async fn fetch_historical_data(
115120 Ok ( data) => {
116121 let data = String :: from_utf8 ( data) ?;
117122 let order: PangeaOrderEvent = serde_json:: from_str ( & data) ?;
118- handle_order_event ( order_book. clone ( ) , order) . await ;
123+ handle_order_event ( order_book. clone ( ) , matching_orders. clone ( ) ,
124+ order) . await ;
119125 }
120126 Err ( e) => {
121127 error ! ( "Error in the stream of historical orders: {e}" ) ;
@@ -134,87 +140,92 @@ async fn fetch_historical_data(
134140 Ok ( last_processed_block)
135141}
136142
143+
137144async fn listen_for_new_deltas (
138145 client : & Client < WsProvider > ,
139146 order_book : & Arc < OrderBook > ,
147+ matching_orders : & Arc < MatchingOrders > ,
140148 mut last_processed_block : i64 ,
141149 contract_h256 : H256 ,
142150) -> Result < ( ) , Error > {
143- let max_retries = 5 ;
144- let mut retry_count = 0 ;
145- let retry_delay = Duration :: from_secs ( 5 ) ;
151+ let mut retry_delay = Duration :: from_secs ( 1 ) ;
152+ let reconnect_interval = Duration :: from_secs ( 10 * 60 ) ;
153+ let mut reconnect_timer = interval ( reconnect_interval) ;
154+ let mut processing = false ;
146155
147156 loop {
148- if retry_count > max_retries {
149- error ! ( "Maximum number of retries exceeded. Exiting listen_for_new_deltas." ) ;
150- return Err ( Error :: MaxRetriesExceeded ) ;
151- }
152-
153- let fuel_chain = match ev ( "CHAIN" ) ?. as_str ( ) {
154- "FUEL" => ChainId :: FUEL ,
155- _ => ChainId :: FUELTESTNET ,
156- } ;
157-
158- let request_deltas = GetSparkOrderRequest {
159- from_block : Bound :: Exact ( last_processed_block + 1 ) ,
160- to_block : Bound :: Subscribe ,
161- market_id__in : HashSet :: from ( [ contract_h256] ) ,
162- chains : HashSet :: from ( [ fuel_chain] ) ,
163- ..Default :: default ( )
164- } ;
165-
166- let stream_deltas_result = client
167- . get_fuel_spark_orders_by_format ( request_deltas, Format :: JsonStream , true )
168- . await ;
169-
170- let stream_deltas = match stream_deltas_result {
171- Ok ( stream) => {
172- retry_count = 0 ;
173- stream
174- }
175- Err ( e) => {
176- error ! ( "Failed to initiate stream: {}" , e) ;
177- retry_count += 1 ;
178- error ! ( "Retrying in {} seconds..." , retry_delay. as_secs( ) ) ;
179- sleep ( retry_delay) . await ;
180- continue ;
181- }
182- } ;
183-
184- pangea_client:: futures:: pin_mut!( stream_deltas) ;
185-
186- while let Some ( data_result) = stream_deltas. next ( ) . await {
187- match data_result {
188- Ok ( data) => {
189- retry_count = 0 ;
190-
191- if let Err ( e) = process_order_data ( & data, order_book, & mut last_processed_block) . await {
192- error ! ( "Failed to process order data: {}" , e) ;
157+ tokio:: select! {
158+ _ = reconnect_timer. tick( ) , if !processing => {
159+ info!( "Scheduled reconnect to refresh connection..." ) ;
160+ processing = false ; // Сбросим состояние processing
161+ } ,
162+ result = async {
163+ processing = true ;
164+ let fuel_chain = match ev( "CHAIN" ) ?. as_str( ) {
165+ "FUEL" => ChainId :: FUEL ,
166+ _ => ChainId :: FUELTESTNET ,
167+ } ;
168+
169+ let request_deltas = GetSparkOrderRequest {
170+ from_block: Bound :: Exact ( last_processed_block + 1 ) ,
171+ to_block: Bound :: Subscribe ,
172+ market_id__in: HashSet :: from( [ contract_h256] ) ,
173+ chains: HashSet :: from( [ fuel_chain] ) ,
174+ ..Default :: default ( )
175+ } ;
176+
177+ match client
178+ . get_fuel_spark_orders_by_format( request_deltas, Format :: JsonStream , true )
179+ . await
180+ {
181+ Ok ( stream_deltas) => {
182+ retry_delay = Duration :: from_secs( 1 ) ;
183+ pangea_client:: futures:: pin_mut!( stream_deltas) ;
184+
185+ while let Some ( data_result) = stream_deltas. next( ) . await {
186+ match data_result {
187+ Ok ( data) => {
188+ if let Err ( e) = process_order_data( & data, order_book, matching_orders, & mut last_processed_block) . await {
189+ error!( "Failed to process order data: {}" , e) ;
190+ }
191+ }
192+ Err ( e) => {
193+ error!( "Error in the stream of new orders (deltas): {}" , e) ;
194+ break ;
195+ }
196+ }
197+ }
198+ }
199+ Err ( e) => {
200+ error!( "Failed to initiate stream: {}" , e) ;
193201 }
194202 }
195- Err ( e) => {
196- error ! ( "Error in the stream of new orders (deltas): {}" , e) ;
197- retry_count += 1 ;
198- error ! ( "Retrying connection in {} seconds..." , retry_delay. as_secs( ) ) ;
199- sleep ( retry_delay) . await ;
200- break ;
203+
204+ info!( "Reconnecting to listen for new deltas in {} seconds..." , retry_delay. as_secs( ) ) ;
205+ sleep( retry_delay) . await ;
206+ retry_delay = ( retry_delay * 2 ) . min( Duration :: from_secs( 60 ) ) ;
207+ Ok :: <( ) , Error >( ( ) )
208+ } => {
209+ processing = false ;
210+ if let Err ( e) = result {
211+ error!( "Error in listen_for_new_deltas: {:?}" , e) ;
201212 }
202- }
213+ } ,
203214 }
204-
205- info ! ( "Reconnecting to listen for new deltas..." ) ;
206- sleep ( retry_delay) . await ;
207215 }
208216}
209217
210218async fn process_order_data (
211219 data : & [ u8 ] ,
212220 order_book : & Arc < OrderBook > ,
221+ matching_orders : & Arc < MatchingOrders > ,
213222 last_processed_block : & mut i64 ,
214223) -> Result < ( ) , Error > {
215224 let data_str = String :: from_utf8 ( data. to_vec ( ) ) ?;
216225 let order_event: PangeaOrderEvent = serde_json:: from_str ( & data_str) ?;
217226 * last_processed_block = order_event. block_number ;
218- handle_order_event ( order_book. clone ( ) , order_event) . await ;
227+ handle_order_event ( order_book. clone ( ) ,
228+ matching_orders. clone ( ) ,
229+ order_event) . await ;
219230 Ok ( ( ) )
220231}
0 commit comments