@@ -54,13 +54,9 @@ use super::{
54
54
} ;
55
55
use crate :: { errors:: ConsumerError , metrics:: Metrics } ;
56
56
57
- const MAX_CONCURRENT_TASKS : usize = 32 ;
58
- const BATCH_SIZE : usize = 100 ;
59
-
60
57
#[ derive( Debug ) ]
61
58
enum ProcessResult {
62
59
Store ( Result < BlockStats , ConsumerError > ) ,
63
- Stream ( Result < BlockStats , ConsumerError > ) ,
64
60
}
65
61
66
62
pub struct BlockExecutor {
@@ -69,6 +65,7 @@ pub struct BlockExecutor {
69
65
fuel_streams : Arc < FuelStreams > ,
70
66
semaphore : Arc < Semaphore > ,
71
67
telemetry : Arc < Telemetry < Metrics > > ,
68
+ concurrent_tasks : usize ,
72
69
}
73
70
74
71
impl BlockExecutor {
@@ -77,14 +74,16 @@ impl BlockExecutor {
77
74
message_broker : & Arc < NatsMessageBroker > ,
78
75
fuel_streams : & Arc < FuelStreams > ,
79
76
telemetry : Arc < Telemetry < Metrics > > ,
77
+ concurrent_tasks : usize ,
80
78
) -> Self {
81
- let semaphore = Arc :: new ( Semaphore :: new ( MAX_CONCURRENT_TASKS ) ) ;
79
+ let semaphore = Arc :: new ( Semaphore :: new ( concurrent_tasks ) ) ;
82
80
Self {
83
81
db,
84
82
semaphore,
85
83
message_broker : message_broker. clone ( ) ,
86
84
fuel_streams : fuel_streams. clone ( ) ,
87
85
telemetry,
86
+ concurrent_tasks,
88
87
}
89
88
}
90
89
@@ -94,22 +93,27 @@ impl BlockExecutor {
94
93
) -> Result < ( ) , ConsumerError > {
95
94
tracing:: info!(
96
95
"Starting consumer with max concurrent tasks: {}" ,
97
- MAX_CONCURRENT_TASKS
96
+ self . concurrent_tasks
98
97
) ;
99
98
100
99
let telemetry = self . telemetry . clone ( ) ;
101
100
let queue = NatsQueue :: BlockImporter ( self . message_broker . clone ( ) ) ;
101
+ let mut join_set = JoinSet :: new ( ) ;
102
102
103
103
while !token. is_cancelled ( ) {
104
- let mut messages = queue. subscribe ( BATCH_SIZE ) . await ?;
105
- let mut join_set = JoinSet :: new ( ) ;
106
- while let Some ( msg) = messages. next ( ) . await {
107
- let msg = msg?;
108
- self . spawn_processing_tasks ( msg, & mut join_set) . await ?;
109
- }
110
- // Wait for all spawned tasks to complete before processing next message
111
- while let Some ( result) = join_set. join_next ( ) . await {
112
- Self :: handle_task_result ( result, & telemetry) . await ?;
104
+ tokio:: select! {
105
+ msg_result = queue. subscribe( self . concurrent_tasks) => {
106
+ let mut messages = msg_result?;
107
+ while let Some ( msg) = messages. next( ) . await {
108
+ let _permit = self . semaphore. acquire( ) . await ?;
109
+ let msg = msg?;
110
+ self . spawn_processing_tasks( msg, & mut join_set, )
111
+ . await ?;
112
+ }
113
+ }
114
+ Some ( result) = join_set. join_next( ) => {
115
+ Self :: handle_task_result( result, & telemetry) . await ?;
116
+ }
113
117
}
114
118
}
115
119
@@ -125,44 +129,45 @@ impl BlockExecutor {
125
129
join_set : & mut JoinSet < Result < ProcessResult , ConsumerError > > ,
126
130
) -> Result < ( ) , ConsumerError > {
127
131
let db = self . db . clone ( ) ;
128
- let semaphore = self . semaphore . clone ( ) ;
129
132
let fuel_streams = self . fuel_streams . clone ( ) ;
130
133
let payload = msg. payload ( ) ;
131
134
let msg_payload = MsgPayload :: decode_json ( & payload) ?. arc ( ) ;
132
135
let packets = Self :: build_packets ( & msg_payload) ;
133
136
134
137
join_set. spawn ( {
135
- let semaphore = semaphore. clone ( ) ;
136
138
let packets = packets. clone ( ) ;
137
139
let msg_payload = msg_payload. clone ( ) ;
138
140
async move {
139
- let _permit = semaphore. acquire ( ) . await ?;
140
141
let result = handle_stores ( & db, & packets, & msg_payload) . await ;
141
142
if let Ok ( stats) = result {
142
143
if stats. error . is_none ( ) {
143
- msg. ack ( ) . await . map_err ( |e| {
144
- tracing:: error!( "Failed to ack message: {:?}" , e) ;
145
- ConsumerError :: MessageBrokerClient ( e)
146
- } ) ?;
144
+ tokio:: spawn ( async move {
145
+ let _ = msg. ack ( ) . await . map_err ( |e| {
146
+ tracing:: error!(
147
+ "Failed to ack message: {:?}" ,
148
+ e
149
+ ) ;
150
+ ConsumerError :: MessageBrokerClient ( e)
151
+ } ) ;
152
+ tracing:: info!(
153
+ "[#{}] Message acknowledged" ,
154
+ stats. block_height
155
+ ) ;
156
+ } ) ;
147
157
}
148
158
return Ok :: < _ , ConsumerError > ( ProcessResult :: Store ( Ok (
149
159
stats,
150
160
) ) ) ;
151
161
}
152
- Ok :: < _ , ConsumerError > ( ProcessResult :: Store ( result) )
153
- }
154
- } ) ;
155
-
156
- join_set. spawn ( {
157
- let semaphore = semaphore. clone ( ) ;
158
- let packets = packets. clone ( ) ;
159
- let msg_payload = msg_payload. clone ( ) ;
160
- let fuel_streams = fuel_streams. clone ( ) ;
161
- async move {
162
- let _permit = semaphore. acquire_owned ( ) . await ?;
163
- let result =
162
+ let result_streams =
164
163
handle_streams ( & fuel_streams, & packets, & msg_payload) . await ;
165
- Ok ( ProcessResult :: Stream ( result) )
164
+ if let Ok ( stream_stats) = result_streams {
165
+ match & stream_stats. error {
166
+ Some ( error) => stream_stats. log_error ( error) ,
167
+ None => stream_stats. log_success ( ) ,
168
+ }
169
+ }
170
+ Ok :: < _ , ConsumerError > ( ProcessResult :: Store ( result) )
166
171
}
167
172
} ) ;
168
173
@@ -185,13 +190,6 @@ impl BlockExecutor {
185
190
None => store_stats. log_success ( ) ,
186
191
}
187
192
}
188
- Ok ( Ok ( ProcessResult :: Stream ( stream_result) ) ) => {
189
- let stream_stats = stream_result?;
190
- match & stream_stats. error {
191
- Some ( error) => stream_stats. log_error ( error) ,
192
- None => stream_stats. log_success ( ) ,
193
- }
194
- }
195
193
Ok ( Err ( e) ) => tracing:: error!( "Task error: {}" , e) ,
196
194
Err ( e) => tracing:: error!( "Task panicked: {}" , e) ,
197
195
}
0 commit comments