1
- use std:: { collections:: HashMap , str:: FromStr , sync:: Arc } ;
1
+ use std:: {
2
+ collections:: { HashMap , VecDeque } ,
3
+ str:: FromStr ,
4
+ sync:: Arc ,
5
+ } ;
2
6
3
7
use anyhow:: anyhow;
4
8
use raiko_core:: {
@@ -16,10 +20,13 @@ use raiko_tasks::{get_task_manager, TaskDescriptor, TaskManager, TaskManagerWrap
16
20
use reth_primitives:: B256 ;
17
21
use tokio:: {
18
22
select,
19
- sync:: { mpsc:: Receiver , Mutex , OwnedSemaphorePermit , Semaphore } ,
23
+ sync:: {
24
+ mpsc:: { Receiver , Sender } ,
25
+ Mutex , OwnedSemaphorePermit , Semaphore ,
26
+ } ,
20
27
} ;
21
28
use tokio_util:: sync:: CancellationToken ;
22
- use tracing:: { error, info, warn} ;
29
+ use tracing:: { debug , error, info, warn} ;
23
30
24
31
use crate :: {
25
32
cache,
@@ -35,32 +42,42 @@ use crate::{
35
42
pub struct ProofActor {
36
43
opts : Opts ,
37
44
chain_specs : SupportedChainSpecs ,
38
- tasks : Arc < Mutex < HashMap < TaskDescriptor , CancellationToken > > > ,
39
45
aggregate_tasks : Arc < Mutex < HashMap < AggregationOnlyRequest , CancellationToken > > > ,
46
+ running_tasks : Arc < Mutex < HashMap < TaskDescriptor , CancellationToken > > > ,
47
+ pending_tasks : Arc < Mutex < VecDeque < ProofRequest > > > ,
40
48
receiver : Receiver < Message > ,
49
+ sender : Sender < Message > ,
41
50
}
42
51
43
52
impl ProofActor {
44
- pub fn new ( receiver : Receiver < Message > , opts : Opts , chain_specs : SupportedChainSpecs ) -> Self {
45
- let tasks = Arc :: new ( Mutex :: new (
53
+ pub fn new (
54
+ sender : Sender < Message > ,
55
+ receiver : Receiver < Message > ,
56
+ opts : Opts ,
57
+ chain_specs : SupportedChainSpecs ,
58
+ ) -> Self {
59
+ let running_tasks = Arc :: new ( Mutex :: new (
46
60
HashMap :: < TaskDescriptor , CancellationToken > :: new ( ) ,
47
61
) ) ;
48
62
let aggregate_tasks = Arc :: new ( Mutex :: new ( HashMap :: <
49
63
AggregationOnlyRequest ,
50
64
CancellationToken ,
51
65
> :: new ( ) ) ) ;
66
+ let pending_tasks = Arc :: new ( Mutex :: new ( VecDeque :: < ProofRequest > :: new ( ) ) ) ;
52
67
53
68
Self {
54
- tasks,
55
- aggregate_tasks,
56
69
opts,
57
70
chain_specs,
71
+ aggregate_tasks,
72
+ running_tasks,
73
+ pending_tasks,
58
74
receiver,
75
+ sender,
59
76
}
60
77
}
61
78
62
79
pub async fn cancel_task ( & mut self , key : TaskDescriptor ) -> HostResult < ( ) > {
63
- let tasks_map = self . tasks . lock ( ) . await ;
80
+ let tasks_map = self . running_tasks . lock ( ) . await ;
64
81
let Some ( task) = tasks_map. get ( & key) else {
65
82
warn ! ( "No task with those keys to cancel" ) ;
66
83
return Ok ( ( ) ) ;
@@ -85,7 +102,7 @@ impl ProofActor {
85
102
Ok ( ( ) )
86
103
}
87
104
88
- pub async fn run_task ( & mut self , proof_request : ProofRequest , _permit : OwnedSemaphorePermit ) {
105
+ pub async fn run_task ( & mut self , proof_request : ProofRequest ) {
89
106
let cancel_token = CancellationToken :: new ( ) ;
90
107
91
108
let Ok ( ( chain_id, blockhash) ) = get_task_data (
@@ -106,10 +123,11 @@ impl ProofActor {
106
123
proof_request. prover . clone ( ) . to_string ( ) ,
107
124
) ) ;
108
125
109
- let mut tasks = self . tasks . lock ( ) . await ;
126
+ let mut tasks = self . running_tasks . lock ( ) . await ;
110
127
tasks. insert ( key. clone ( ) , cancel_token. clone ( ) ) ;
128
+ let sender = self . sender . clone ( ) ;
111
129
112
- let tasks = self . tasks . clone ( ) ;
130
+ let tasks = self . running_tasks . clone ( ) ;
113
131
let opts = self . opts . clone ( ) ;
114
132
let chain_specs = self . chain_specs . clone ( ) ;
115
133
@@ -118,7 +136,7 @@ impl ProofActor {
118
136
_ = cancel_token. cancelled( ) => {
119
137
info!( "Task cancelled" ) ;
120
138
}
121
- result = Self :: handle_message( proof_request, key. clone( ) , & opts, & chain_specs) => {
139
+ result = Self :: handle_message( proof_request. clone ( ) , key. clone( ) , & opts, & chain_specs) => {
122
140
match result {
123
141
Ok ( status) => {
124
142
info!( "Host handling message: {status:?}" ) ;
@@ -131,6 +149,11 @@ impl ProofActor {
131
149
}
132
150
let mut tasks = tasks. lock ( ) . await ;
133
151
tasks. remove ( & key) ;
152
+ // notify complete task to let next pending task run
153
+ sender
154
+ . send ( Message :: TaskComplete ( proof_request) )
155
+ . await
156
+ . expect ( "Couldn't send message" ) ;
134
157
} ) ;
135
158
}
136
159
@@ -203,21 +226,47 @@ impl ProofActor {
203
226
}
204
227
205
228
pub async fn run ( & mut self ) {
229
+ // recv() is protected by outside mpsc, no lock needed here
206
230
let semaphore = Arc :: new ( Semaphore :: new ( self . opts . concurrency_limit ) ) ;
207
-
208
231
while let Some ( message) = self . receiver . recv ( ) . await {
209
232
match message {
210
233
Message :: Cancel ( key) => {
234
+ debug ! ( "Message::Cancel task: {key:?}" ) ;
211
235
if let Err ( error) = self . cancel_task ( key) . await {
212
236
error ! ( "Failed to cancel task: {error}" )
213
237
}
214
238
}
215
239
Message :: Task ( proof_request) => {
216
- let permit = Arc :: clone ( & semaphore)
217
- . acquire_owned ( )
218
- . await
219
- . expect ( "Couldn't acquire permit" ) ;
220
- self . run_task ( proof_request, permit) . await ;
240
+ debug ! ( "Message::Task proof_request: {proof_request:?}" ) ;
241
+ let running_task_count = self . running_tasks . lock ( ) . await . len ( ) ;
242
+ if running_task_count < self . opts . concurrency_limit {
243
+ info ! ( "Running task {proof_request:?}" ) ;
244
+ self . run_task ( proof_request) . await ;
245
+ } else {
246
+ info ! (
247
+ "Task concurrency limit reached, current running {running_task_count:?}, pending: {:?}" ,
248
+ self . pending_tasks. lock( ) . await . len( )
249
+ ) ;
250
+ let mut pending_tasks = self . pending_tasks . lock ( ) . await ;
251
+ pending_tasks. push_back ( proof_request) ;
252
+ }
253
+ }
254
+ Message :: TaskComplete ( req) => {
255
+ // pop up pending task if any task complete
256
+ debug ! ( "Message::TaskComplete: {req:?}" ) ;
257
+ info ! (
258
+ "task completed, current running {:?}, pending: {:?}" ,
259
+ self . running_tasks. lock( ) . await . len( ) ,
260
+ self . pending_tasks. lock( ) . await . len( )
261
+ ) ;
262
+ let mut pending_tasks = self . pending_tasks . lock ( ) . await ;
263
+ if let Some ( proof_request) = pending_tasks. pop_front ( ) {
264
+ info ! ( "Pop out pending task {proof_request:?}" ) ;
265
+ self . sender
266
+ . send ( Message :: Task ( proof_request) )
267
+ . await
268
+ . expect ( "Couldn't send message" ) ;
269
+ }
221
270
}
222
271
Message :: CancelAggregate ( request) => {
223
272
if let Err ( error) = self . cancel_aggregation_task ( request) . await {
@@ -326,7 +375,7 @@ pub async fn handle_proof(
326
375
store : Option < & mut TaskManagerWrapper > ,
327
376
) -> HostResult < Proof > {
328
377
info ! (
329
- "# Generating proof for block {} on {}" ,
378
+ "Generating proof for block {} on {}" ,
330
379
proof_request. block_number, proof_request. network
331
380
) ;
332
381
0 commit comments