18
18
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
20
20
use std:: collections:: BTreeMap ;
21
- use std:: time:: { Duration , Instant } ;
21
+ use std:: sync:: Arc ;
22
+ use std:: time:: Duration ;
22
23
23
24
use anyhow:: { bail, Context } ;
24
25
use quickwit_metastore:: checkpoint:: PartitionId ;
@@ -34,35 +35,78 @@ use super::message::PreProcessedMessage;
34
35
35
36
#[ derive( Clone ) ]
36
37
pub struct QueueSharedState {
37
- pub metastore : MetastoreServiceClient ,
38
+ metastore : MetastoreServiceClient ,
38
39
pub index_uid : IndexUid ,
39
40
pub source_id : String ,
40
41
/// Duration after which the processing of a shard is considered stale and
41
42
/// should be reacquired
42
- pub reacquire_grace_period : Duration ,
43
- pub max_age : Option < u32 > ,
44
- pub max_count : Option < u32 > ,
45
- pub last_initiated_pruning : Instant ,
46
- pub pruning_interval : Duration ,
43
+ reacquire_grace_period : Duration ,
44
+ _cleanup_handle : Arc < ( ) > ,
47
45
}
48
46
49
47
impl QueueSharedState {
50
- async fn clean_partitions ( & self ) {
51
- if self . max_count . is_none ( ) && self . max_age . is_none ( ) {
52
- return ;
48
+ /// Create a shared state service and runs a cleanup task that prunes shards
49
+ /// in the background
50
+ pub fn new (
51
+ metastore : MetastoreServiceClient ,
52
+ index_uid : IndexUid ,
53
+ source_id : String ,
54
+ reacquire_grace_period : Duration ,
55
+ max_age : Option < u32 > ,
56
+ max_count : Option < u32 > ,
57
+ pruning_interval : Duration ,
58
+ ) -> Self {
59
+ let cleanup_handle = Arc :: new ( ( ) ) ;
60
+ tokio:: spawn ( Self :: run_cleanup_task (
61
+ metastore. clone ( ) ,
62
+ index_uid. clone ( ) ,
63
+ source_id. clone ( ) ,
64
+ max_age,
65
+ max_count,
66
+ pruning_interval,
67
+ cleanup_handle. clone ( ) ,
68
+ ) ) ;
69
+ Self {
70
+ metastore,
71
+ index_uid,
72
+ source_id,
73
+ reacquire_grace_period,
74
+ _cleanup_handle : cleanup_handle,
53
75
}
54
- let result = self
55
- . metastore
56
- . prune_shards ( PruneShardsRequest {
57
- index_uid : Some ( self . index_uid . clone ( ) ) ,
58
- source_id : self . source_id . clone ( ) ,
59
- max_age : self . max_age ,
60
- max_count : self . max_count ,
61
- } )
62
- . await ;
63
- if let Err ( err) = result {
64
- error ! ( error = ?err, "failed to prune shards" ) ;
76
+ }
77
+
78
+ async fn run_cleanup_task (
79
+ metastore : MetastoreServiceClient ,
80
+ index_uid : IndexUid ,
81
+ source_id : String ,
82
+ max_age : Option < u32 > ,
83
+ max_count : Option < u32 > ,
84
+ pruning_interval : Duration ,
85
+ owner_handle : Arc < ( ) > ,
86
+ ) {
87
+ if max_count. is_none ( ) && max_age. is_none ( ) {
88
+ return ;
65
89
}
90
+ tokio:: spawn ( async move {
91
+ let mut interval = tokio:: time:: interval ( pruning_interval) ;
92
+ loop {
93
+ interval. tick ( ) . await ;
94
+ if Arc :: strong_count ( & owner_handle) == 1 {
95
+ break ;
96
+ }
97
+ let result: Result < _ , _ > = metastore
98
+ . prune_shards ( PruneShardsRequest {
99
+ index_uid : Some ( index_uid. clone ( ) ) ,
100
+ source_id : source_id. clone ( ) ,
101
+ max_age,
102
+ max_count,
103
+ } )
104
+ . await ;
105
+ if let Err ( err) = result {
106
+ error ! ( error = ?err, "failed to prune shards" ) ;
107
+ }
108
+ }
109
+ } ) ;
66
110
}
67
111
68
112
/// Tries to acquire the ownership for the provided messages from the global
@@ -75,13 +119,6 @@ impl QueueSharedState {
75
119
publish_token : & str ,
76
120
partitions : Vec < PartitionId > ,
77
121
) -> anyhow:: Result < Vec < ( PartitionId , Position ) > > {
78
- if self . last_initiated_pruning . elapsed ( ) > self . pruning_interval {
79
- let self_cloned = self . clone ( ) ;
80
- tokio:: spawn ( async move {
81
- self_cloned. clean_partitions ( ) . await ;
82
- } ) ;
83
- self . last_initiated_pruning = Instant :: now ( ) ;
84
- }
85
122
let open_shard_subrequests = partitions
86
123
. iter ( )
87
124
. enumerate ( )
@@ -323,10 +360,7 @@ pub mod shared_state_for_tests {
323
360
index_uid,
324
361
source_id : "test-queue-src" . to_string ( ) ,
325
362
reacquire_grace_period : Duration :: from_secs ( 10 ) ,
326
- last_initiated_pruning : Instant :: now ( ) ,
327
- max_age : None ,
328
- max_count : None ,
329
- pruning_interval : Duration :: from_secs ( 10 ) ,
363
+ _cleanup_handle : Arc :: new ( ( ) ) ,
330
364
}
331
365
}
332
366
}
@@ -378,10 +412,7 @@ mod tests {
378
412
index_uid,
379
413
source_id : "test-sqs-source" . to_string ( ) ,
380
414
reacquire_grace_period : Duration :: from_secs ( 10 ) ,
381
- last_initiated_pruning : Instant :: now ( ) ,
382
- max_age : None ,
383
- max_count : None ,
384
- pruning_interval : Duration :: from_secs ( 10 ) ,
415
+ _cleanup_handle : Arc :: new ( ( ) ) ,
385
416
} ;
386
417
387
418
let aquired = shared_state
@@ -411,10 +442,7 @@ mod tests {
411
442
index_uid,
412
443
source_id : "test-sqs-source" . to_string ( ) ,
413
444
reacquire_grace_period : Duration :: from_secs ( 10 ) ,
414
- last_initiated_pruning : Instant :: now ( ) ,
415
- max_age : None ,
416
- max_count : None ,
417
- pruning_interval : Duration :: from_secs ( 10 ) ,
445
+ _cleanup_handle : Arc :: new ( ( ) ) ,
418
446
} ;
419
447
420
448
let acquired = shared_state
@@ -444,10 +472,7 @@ mod tests {
444
472
index_uid,
445
473
source_id : "test-sqs-source" . to_string ( ) ,
446
474
reacquire_grace_period : Duration :: from_secs ( 10 ) ,
447
- last_initiated_pruning : Instant :: now ( ) ,
448
- max_age : None ,
449
- max_count : None ,
450
- pruning_interval : Duration :: from_secs ( 10 ) ,
475
+ _cleanup_handle : Arc :: new ( ( ) ) ,
451
476
} ;
452
477
453
478
let aquired = shared_state
@@ -481,10 +506,7 @@ mod tests {
481
506
index_uid,
482
507
source_id : "test-sqs-source" . to_string ( ) ,
483
508
reacquire_grace_period : Duration :: from_secs ( 10 ) ,
484
- last_initiated_pruning : Instant :: now ( ) ,
485
- max_age : None ,
486
- max_count : None ,
487
- pruning_interval : Duration :: from_secs ( 10 ) ,
509
+ _cleanup_handle : Arc :: new ( ( ) ) ,
488
510
} ;
489
511
490
512
let checkpointed_msg = checkpoint_messages ( & mut shared_state, "token1" , source_messages)
0 commit comments