@@ -6,7 +6,7 @@ use crate::single_disk_farm::metrics::{SectorState, SingleDiskFarmMetrics};
6
6
use crate :: single_disk_farm:: {
7
7
BackgroundTaskError , Handlers , PlotMetadataHeader , RESERVED_PLOT_METADATA ,
8
8
} ;
9
- use async_lock:: { Mutex as AsyncMutex , RwLock as AsyncRwLock , Semaphore } ;
9
+ use async_lock:: { Mutex as AsyncMutex , RwLock as AsyncRwLock , Semaphore , SemaphoreGuard } ;
10
10
use futures:: channel:: { mpsc, oneshot} ;
11
11
use futures:: stream:: FuturesOrdered ;
12
12
use futures:: { select, FutureExt , SinkExt , StreamExt } ;
@@ -123,8 +123,30 @@ where
123
123
max_plotting_sectors_per_farm,
124
124
} = plotting_options;
125
125
126
+ let sector_plotting_options = & sector_plotting_options;
126
127
let plotting_semaphore = Semaphore :: new ( max_plotting_sectors_per_farm. get ( ) ) ;
127
128
let mut sectors_being_plotted = FuturesOrdered :: new ( ) ;
129
+ // Channel size is intentionally unbounded for easier analysis, but it is bounded by plotting
130
+ // semaphore in practice due to permit stored in `SectorPlottingResult`
131
+ let ( sector_plotting_result_sender, mut sector_plotting_result_receiver) = mpsc:: unbounded ( ) ;
132
+ let process_plotting_result_fut = async move {
133
+ while let Some ( sector_plotting_result) = sector_plotting_result_receiver. next ( ) . await {
134
+ process_plotting_result (
135
+ sector_plotting_result,
136
+ sectors_metadata,
137
+ sectors_being_modified,
138
+ & mut metadata_header,
139
+ Arc :: clone ( & sector_plotting_options. metadata_file ) ,
140
+ )
141
+ . await ?;
142
+ }
143
+
144
+ unreachable ! (
145
+ "Stream will not end before the rest of the plotting process is shutting down"
146
+ ) ;
147
+ } ;
148
+ let process_plotting_result_fut = process_plotting_result_fut. fuse ( ) ;
149
+ let mut process_plotting_result_fut = pin ! ( process_plotting_result_fut) ;
128
150
129
151
// Wait for new sectors to plot from `sectors_to_plot_receiver` and wait for sectors that
130
152
// already started plotting to finish plotting and then update metadata header
@@ -138,7 +160,7 @@ where
138
160
let sector_index = sector_to_plot. sector_index;
139
161
let sector_plotting_init_fut = plot_single_sector(
140
162
sector_to_plot,
141
- & sector_plotting_options,
163
+ sector_plotting_options,
142
164
sectors_metadata,
143
165
sectors_being_modified,
144
166
& plotting_semaphore,
@@ -168,25 +190,23 @@ where
168
190
break ;
169
191
}
170
192
maybe_sector_plotting_result = sectors_being_plotted. select_next_some( ) => {
171
- process_plotting_result(
172
- maybe_sector_plotting_result?,
173
- sectors_metadata,
174
- sectors_being_modified,
175
- & mut metadata_header,
176
- Arc :: clone( & sector_plotting_options. metadata_file)
177
- ) . await ?;
193
+ sector_plotting_result_sender
194
+ . unbounded_send( maybe_sector_plotting_result?)
195
+ . expect( "Sending means receiver is not dropped yet; qed" ) ;
196
+ }
197
+ result = process_plotting_result_fut => {
198
+ return result;
178
199
}
179
200
}
180
201
}
181
202
}
182
203
maybe_sector_plotting_result = sectors_being_plotted. select_next_some( ) => {
183
- process_plotting_result(
184
- maybe_sector_plotting_result?,
185
- sectors_metadata,
186
- sectors_being_modified,
187
- & mut metadata_header,
188
- Arc :: clone( & sector_plotting_options. metadata_file)
189
- ) . await ?;
204
+ sector_plotting_result_sender
205
+ . unbounded_send( maybe_sector_plotting_result?)
206
+ . expect( "Sending means receiver is not dropped yet; qed" ) ;
207
+ }
208
+ result = process_plotting_result_fut => {
209
+ return result;
190
210
}
191
211
}
192
212
}
@@ -195,7 +215,7 @@ where
195
215
}
196
216
197
217
async fn process_plotting_result (
198
- sector_plotting_result : SectorPlottingResult ,
218
+ sector_plotting_result : SectorPlottingResult < ' _ > ,
199
219
sectors_metadata : & AsyncRwLock < Vec < SectorMetadataChecksummed > > ,
200
220
sectors_being_modified : & AsyncRwLock < HashSet < SectorIndex > > ,
201
221
metadata_header : & mut PlotMetadataHeader ,
@@ -205,6 +225,7 @@ async fn process_plotting_result(
205
225
sector_metadata,
206
226
replotting,
207
227
last_queued,
228
+ plotting_permit,
208
229
} = sector_plotting_result;
209
230
210
231
let sector_index = sector_metadata. sector_index ;
@@ -241,6 +262,8 @@ async fn process_plotting_result(
241
262
}
242
263
}
243
264
265
+ drop ( plotting_permit) ;
266
+
244
267
Ok ( ( ) )
245
268
}
246
269
@@ -250,10 +273,11 @@ enum PlotSingleSectorResult<F> {
250
273
FatalError ( PlottingError ) ,
251
274
}
252
275
253
- struct SectorPlottingResult {
276
+ struct SectorPlottingResult < ' a > {
254
277
sector_metadata : SectorMetadataChecksummed ,
255
278
replotting : bool ,
256
279
last_queued : bool ,
280
+ plotting_permit : SemaphoreGuard < ' a > ,
257
281
}
258
282
259
283
async fn plot_single_sector < ' a , NC > (
@@ -262,7 +286,9 @@ async fn plot_single_sector<'a, NC>(
262
286
sectors_metadata : & ' a AsyncRwLock < Vec < SectorMetadataChecksummed > > ,
263
287
sectors_being_modified : & ' a AsyncRwLock < HashSet < SectorIndex > > ,
264
288
plotting_semaphore : & ' a Semaphore ,
265
- ) -> PlotSingleSectorResult < impl Future < Output = Result < SectorPlottingResult , PlottingError > > + ' a >
289
+ ) -> PlotSingleSectorResult <
290
+ impl Future < Output = Result < SectorPlottingResult < ' a > , PlottingError > > + ' a ,
291
+ >
266
292
where
267
293
NC : NodeClient ,
268
294
{
@@ -478,12 +504,11 @@ where
478
504
. sector_update
479
505
. call_simple ( & ( sector_index, sector_state) ) ;
480
506
481
- drop ( plotting_permit) ;
482
-
483
507
Ok ( SectorPlottingResult {
484
508
sector_metadata,
485
509
replotting,
486
510
last_queued,
511
+ plotting_permit,
487
512
} )
488
513
} )
489
514
}
0 commit comments