@@ -2,6 +2,7 @@ use std::collections::BTreeMap;
2
2
use std:: fmt;
3
3
use std:: future:: Future ;
4
4
use std:: path:: PathBuf ;
5
+ use std:: pin:: Pin ;
5
6
use std:: str:: FromStr ;
6
7
use std:: sync:: Arc ;
7
8
@@ -121,6 +122,14 @@ impl fmt::Display for SegmentKey {
121
122
}
122
123
}
123
124
125
+ /// takes the new durable frame_no and returns a future
126
+ pub type OnStoreCallback = Box <
127
+ dyn FnOnce ( u64 ) -> Pin < Box < dyn Future < Output = ( ) > + Send + Sync + ' static > >
128
+ + Send
129
+ + Sync
130
+ + ' static ,
131
+ > ;
132
+
124
133
pub trait Storage : Send + Sync + ' static {
125
134
type Segment : Segment ;
126
135
type Config ;
@@ -133,7 +142,8 @@ pub trait Storage: Send + Sync + 'static {
133
142
namespace : & NamespaceName ,
134
143
seg : Self :: Segment ,
135
144
config_override : Option < Arc < Self :: Config > > ,
136
- ) -> impl Future < Output = u64 > + Send + Sync + ' static ;
145
+ on_store : OnStoreCallback ,
146
+ ) ;
137
147
138
148
fn durable_frame_no_sync (
139
149
& self ,
@@ -190,8 +200,8 @@ impl Storage for NoStorage {
190
200
_namespace : & NamespaceName ,
191
201
_seg : Self :: Segment ,
192
202
_config : Option < Arc < Self :: Config > > ,
193
- ) -> impl Future < Output = u64 > + Send + Sync + ' static {
194
- std :: future :: ready ( u64 :: MAX )
203
+ _on_store : OnStoreCallback ,
204
+ ) {
195
205
}
196
206
197
207
async fn durable_frame_no (
@@ -286,12 +296,15 @@ impl<IO: Io> TestStorage<IO> {
286
296
pub fn new_io ( store : bool , io : IO ) -> Self {
287
297
let dir = tempdir ( ) . unwrap ( ) ;
288
298
Self {
289
- inner : Arc :: new ( TestStorageInner {
290
- dir,
291
- stored : Default :: default ( ) ,
292
- io,
293
- store,
294
- } . into ( ) ) ,
299
+ inner : Arc :: new (
300
+ TestStorageInner {
301
+ dir,
302
+ stored : Default :: default ( ) ,
303
+ io,
304
+ store,
305
+ }
306
+ . into ( ) ,
307
+ ) ,
295
308
}
296
309
}
297
310
}
@@ -305,14 +318,17 @@ impl<IO: Io> Storage for TestStorage<IO> {
305
318
namespace : & NamespaceName ,
306
319
seg : Self :: Segment ,
307
320
_config : Option < Arc < Self :: Config > > ,
308
- ) -> impl Future < Output = u64 > + Send + Sync + ' static {
321
+ on_store : OnStoreCallback ,
322
+ ) {
309
323
let mut inner = self . inner . lock ( ) ;
310
324
if inner. store {
311
325
let id = uuid:: Uuid :: new_v4 ( ) ;
312
326
let out_path = inner. dir . path ( ) . join ( id. to_string ( ) ) ;
313
327
let out_file = inner. io . open ( true , true , true , & out_path) . unwrap ( ) ;
314
- let index = tokio:: runtime:: Handle :: current ( ) . block_on ( seg. compact ( & out_file, id) ) . unwrap ( ) ;
315
- let end_frame_no = seg. header ( ) . last_committed ( ) ;
328
+ let index = tokio:: runtime:: Handle :: current ( )
329
+ . block_on ( seg. compact ( & out_file, id) )
330
+ . unwrap ( ) ;
331
+ let end_frame_no = seg. header ( ) . last_committed ( ) ;
316
332
let key = SegmentKey {
317
333
start_frame_no : seg. header ( ) . start_frame_no . get ( ) ,
318
334
end_frame_no,
@@ -323,9 +339,7 @@ impl<IO: Io> Storage for TestStorage<IO> {
323
339
. entry ( namespace. clone ( ) )
324
340
. or_default ( )
325
341
. insert ( key, ( out_path, index) ) ;
326
- std:: future:: ready ( end_frame_no)
327
- } else {
328
- std:: future:: ready ( u64:: MAX )
342
+ tokio:: runtime:: Handle :: current ( ) . block_on ( on_store ( end_frame_no) )
329
343
}
330
344
}
331
345
@@ -354,12 +368,10 @@ impl<IO: Io> Storage for TestStorage<IO> {
354
368
) -> u64 {
355
369
let inner = self . inner . lock ( ) ;
356
370
if inner. store {
357
- let Some ( segs) = inner. stored . get ( namespace) else { return 0 } ;
358
- segs
359
- . keys ( )
360
- . map ( |k| k. end_frame_no )
361
- . max ( )
362
- . unwrap_or ( 0 )
371
+ let Some ( segs) = inner. stored . get ( namespace) else {
372
+ return 0 ;
373
+ } ;
374
+ segs. keys ( ) . map ( |k| k. end_frame_no ) . max ( ) . unwrap_or ( 0 )
363
375
} else {
364
376
u64:: MAX
365
377
}
@@ -374,9 +386,10 @@ impl<IO: Io> Storage for TestStorage<IO> {
374
386
let inner = self . inner . lock ( ) ;
375
387
if inner. store {
376
388
if let Some ( segs) = inner. stored . get ( namespace) {
377
- let Some ( ( key, _path) ) = segs. iter ( ) . find ( |( k, _) | k. includes ( frame_no) )
378
- else { return Err ( Error :: FrameNotFound ( frame_no) ) } ;
379
- return Ok ( * key)
389
+ let Some ( ( key, _path) ) = segs. iter ( ) . find ( |( k, _) | k. includes ( frame_no) ) else {
390
+ return Err ( Error :: FrameNotFound ( frame_no) ) ;
391
+ } ;
392
+ return Ok ( * key) ;
380
393
} else {
381
394
panic ! ( "namespace not found" ) ;
382
395
}
@@ -394,12 +407,9 @@ impl<IO: Io> Storage for TestStorage<IO> {
394
407
let inner = self . inner . lock ( ) ;
395
408
if inner. store {
396
409
match inner. stored . get ( namespace) {
397
- Some ( segs) => {
398
- Ok ( segs. get ( & key) . unwrap ( ) . 1 . clone ( ) )
399
- }
410
+ Some ( segs) => Ok ( segs. get ( & key) . unwrap ( ) . 1 . clone ( ) ) ,
400
411
None => panic ! ( "unknown namespace" ) ,
401
412
}
402
-
403
413
} else {
404
414
panic ! ( "not storing" )
405
415
}
@@ -421,14 +431,12 @@ impl<IO: Io> Storage for TestStorage<IO> {
421
431
}
422
432
None => panic ! ( "unknown namespace" ) ,
423
433
}
424
-
425
434
} else {
426
435
panic ! ( "not storing" )
427
436
}
428
437
}
429
438
}
430
439
431
- #[ derive( Debug ) ]
432
440
pub struct StoreSegmentRequest < C , S > {
433
441
namespace : NamespaceName ,
434
442
/// Path to the segment. Read-only for bottomless
@@ -439,4 +447,21 @@ pub struct StoreSegmentRequest<C, S> {
439
447
/// alternative configuration to use with the storage layer.
440
448
/// e.g: S3 overrides
441
449
storage_config_override : Option < Arc < C > > ,
450
+ /// Called after the segment was stored, with the new durable index
451
+ on_store_callback : OnStoreCallback ,
452
+ }
453
+
454
+ impl < C , S > fmt:: Debug for StoreSegmentRequest < C , S >
455
+ where
456
+ C : fmt:: Debug ,
457
+ S : fmt:: Debug ,
458
+ {
459
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
460
+ f. debug_struct ( "StoreSegmentRequest" )
461
+ . field ( "namespace" , & self . namespace )
462
+ . field ( "segment" , & self . segment )
463
+ . field ( "created_at" , & self . created_at )
464
+ . field ( "storage_config_override" , & self . storage_config_override )
465
+ . finish ( )
466
+ }
442
467
}
0 commit comments