@@ -16,13 +16,15 @@ use everscale_types::prelude::*;
16
16
use futures_util:: future:: BoxFuture ;
17
17
use futures_util:: { FutureExt , StreamExt } ;
18
18
use parking_lot:: RwLock ;
19
+ use scopeguard:: defer;
19
20
use serde:: { Deserialize , Serialize } ;
20
21
use tarpc:: server:: Channel ;
22
+ use tokio:: sync:: watch;
23
+ use tokio:: task:: AbortHandle ;
21
24
use tycho_block_util:: config:: build_elections_data_to_sign;
22
25
use tycho_block_util:: state:: RefMcStateHandle ;
23
26
use tycho_core:: block_strider:: {
24
- GcSubscriber , ManualCompaction , ManualCompactionTrigger , ManualGcTrigger , StateSubscriber ,
25
- StateSubscriberContext ,
27
+ GcSubscriber , ManualGcTrigger , StateSubscriber , StateSubscriberContext ,
26
28
} ;
27
29
use tycho_core:: blockchain_rpc:: BlockchainRpcClient ;
28
30
use tycho_network:: Network ;
@@ -150,13 +152,7 @@ impl Drop for ControlEndpoint {
150
152
}
151
153
152
154
pub struct ControlServerBuilder <
153
- MandatoryFields = (
154
- Network ,
155
- Storage ,
156
- GcSubscriber ,
157
- BlockchainRpcClient ,
158
- ManualCompaction ,
159
- ) ,
155
+ MandatoryFields = ( Network , Storage , GcSubscriber , BlockchainRpcClient ) ,
160
156
> {
161
157
mandatory_fields : MandatoryFields ,
162
158
memory_profiler : Option < Arc < dyn MemoryProfiler > > ,
@@ -166,8 +162,7 @@ pub struct ControlServerBuilder<
166
162
167
163
impl ControlServerBuilder {
168
164
pub async fn build ( self , version : ControlServerVersion ) -> Result < ControlServer > {
169
- let ( network, storage, gc_subscriber, blockchain_rpc_client, manual_compaction) =
170
- self . mandatory_fields ;
165
+ let ( network, storage, gc_subscriber, blockchain_rpc_client) = self . mandatory_fields ;
171
166
let memory_profiler = self
172
167
. memory_profiler
173
168
. unwrap_or_else ( || Arc :: new ( StubMemoryProfiler ) ) ;
@@ -207,6 +202,8 @@ impl ControlServerBuilder {
207
202
} ,
208
203
} ;
209
204
205
+ let manual_compaction = ManualCompaction :: new ( storage. clone ( ) ) ;
206
+
210
207
Ok ( ControlServer {
211
208
inner : Arc :: new ( Inner {
212
209
node_info,
@@ -224,71 +221,53 @@ impl ControlServerBuilder {
224
221
}
225
222
}
226
223
227
- impl < T2 , T3 , T4 , T5 > ControlServerBuilder < ( ( ) , T2 , T3 , T4 , T5 ) > {
228
- pub fn with_network (
229
- self ,
230
- network : & Network ,
231
- ) -> ControlServerBuilder < ( Network , T2 , T3 , T4 , T5 ) > {
232
- let ( _, t2, t3, t4, t5) = self . mandatory_fields ;
224
+ impl < T2 , T3 , T4 > ControlServerBuilder < ( ( ) , T2 , T3 , T4 ) > {
225
+ pub fn with_network ( self , network : & Network ) -> ControlServerBuilder < ( Network , T2 , T3 , T4 ) > {
226
+ let ( _, t2, t3, t4) = self . mandatory_fields ;
233
227
ControlServerBuilder {
234
- mandatory_fields : ( network. clone ( ) , t2, t3, t4, t5 ) ,
228
+ mandatory_fields : ( network. clone ( ) , t2, t3, t4) ,
235
229
memory_profiler : self . memory_profiler ,
236
230
validator_keypair : self . validator_keypair ,
237
231
collator : self . collator ,
238
232
}
239
233
}
240
234
}
241
235
242
- impl < T1 , T3 , T4 , T5 > ControlServerBuilder < ( T1 , ( ) , T3 , T4 , T5 ) > {
243
- pub fn with_storage ( self , storage : Storage ) -> ControlServerBuilder < ( T1 , Storage , T3 , T4 , T5 ) > {
244
- let ( t1, _, t3, t4, t5 ) = self . mandatory_fields ;
236
+ impl < T1 , T3 , T4 > ControlServerBuilder < ( T1 , ( ) , T3 , T4 ) > {
237
+ pub fn with_storage ( self , storage : Storage ) -> ControlServerBuilder < ( T1 , Storage , T3 , T4 ) > {
238
+ let ( t1, _, t3, t4) = self . mandatory_fields ;
245
239
ControlServerBuilder {
246
- mandatory_fields : ( t1, storage, t3, t4, t5 ) ,
240
+ mandatory_fields : ( t1, storage, t3, t4) ,
247
241
memory_profiler : self . memory_profiler ,
248
242
validator_keypair : self . validator_keypair ,
249
243
collator : self . collator ,
250
244
}
251
245
}
252
246
}
253
247
254
- impl < T1 , T2 , T4 , T5 > ControlServerBuilder < ( T1 , T2 , ( ) , T4 , T5 ) > {
248
+ impl < T1 , T2 , T4 > ControlServerBuilder < ( T1 , T2 , ( ) , T4 ) > {
255
249
pub fn with_gc_subscriber (
256
250
self ,
257
251
gc_subscriber : GcSubscriber ,
258
- ) -> ControlServerBuilder < ( T1 , T2 , GcSubscriber , T4 , T5 ) > {
259
- let ( t1, t2, _, t4, t5 ) = self . mandatory_fields ;
252
+ ) -> ControlServerBuilder < ( T1 , T2 , GcSubscriber , T4 ) > {
253
+ let ( t1, t2, _, t4) = self . mandatory_fields ;
260
254
ControlServerBuilder {
261
- mandatory_fields : ( t1, t2, gc_subscriber, t4, t5 ) ,
255
+ mandatory_fields : ( t1, t2, gc_subscriber, t4) ,
262
256
memory_profiler : self . memory_profiler ,
263
257
validator_keypair : self . validator_keypair ,
264
258
collator : self . collator ,
265
259
}
266
260
}
267
261
}
268
262
269
- impl < T1 , T2 , T3 , T5 > ControlServerBuilder < ( T1 , T2 , T3 , ( ) , T5 ) > {
263
+ impl < T1 , T2 , T3 > ControlServerBuilder < ( T1 , T2 , T3 , ( ) ) > {
270
264
pub fn with_blockchain_rpc_client (
271
265
self ,
272
266
client : BlockchainRpcClient ,
273
- ) -> ControlServerBuilder < ( T1 , T2 , T3 , BlockchainRpcClient , T5 ) > {
274
- let ( t1, t2, t3, _, t5) = self . mandatory_fields ;
275
- ControlServerBuilder {
276
- mandatory_fields : ( t1, t2, t3, client, t5) ,
277
- memory_profiler : self . memory_profiler ,
278
- validator_keypair : self . validator_keypair ,
279
- collator : self . collator ,
280
- }
281
- }
282
- }
283
-
284
- impl < T1 , T2 , T3 , T4 > ControlServerBuilder < ( T1 , T2 , T3 , T4 , ( ) ) > {
285
- pub fn with_manual_compaction (
286
- self ,
287
- manual_compaction : ManualCompaction ,
288
- ) -> ControlServerBuilder < ( T1 , T2 , T3 , T4 , ManualCompaction ) > {
289
- let ( t1, t2, t3, t4, _) = self . mandatory_fields ;
267
+ ) -> ControlServerBuilder < ( T1 , T2 , T3 , BlockchainRpcClient ) > {
268
+ let ( t1, t2, t3, _) = self . mandatory_fields ;
290
269
ControlServerBuilder {
291
- mandatory_fields : ( t1, t2, t3, t4 , manual_compaction ) ,
270
+ mandatory_fields : ( t1, t2, t3, client ) ,
292
271
memory_profiler : self . memory_profiler ,
293
272
validator_keypair : self . validator_keypair ,
294
273
collator : self . collator ,
@@ -320,9 +299,9 @@ pub struct ControlServer {
320
299
}
321
300
322
301
impl ControlServer {
323
- pub fn builder ( ) -> ControlServerBuilder < ( ( ) , ( ) , ( ) , ( ) , ( ) ) > {
302
+ pub fn builder ( ) -> ControlServerBuilder < ( ( ) , ( ) , ( ) , ( ) ) > {
324
303
ControlServerBuilder {
325
- mandatory_fields : ( ( ) , ( ) , ( ) , ( ) , ( ) ) ,
304
+ mandatory_fields : ( ( ) , ( ) , ( ) , ( ) ) ,
326
305
memory_profiler : None ,
327
306
validator_keypair : None ,
328
307
collator : None ,
@@ -468,7 +447,7 @@ impl proto::ControlServer for ControlServer {
468
447
}
469
448
470
449
async fn trigger_compaction ( self , _: Context , req : proto:: TriggerCompactionRequest ) {
471
- self . inner . manual_compaction . trigger_compaction ( req. into ( ) ) ;
450
+ self . inner . manual_compaction . trigger_compaction ( req) ;
472
451
}
473
452
474
453
async fn set_memory_profiler_enabled ( self , _: Context , enabled : bool ) -> bool {
@@ -854,16 +833,6 @@ impl From<proto::TriggerGcRequest> for ManualGcTrigger {
854
833
}
855
834
}
856
835
857
- impl From < proto:: TriggerCompactionRequest > for ManualCompactionTrigger {
858
- fn from ( value : proto:: TriggerCompactionRequest ) -> Self {
859
- match value {
860
- proto:: TriggerCompactionRequest :: Base => Self :: Base ,
861
- proto:: TriggerCompactionRequest :: Mempool => Self :: Mempool ,
862
- proto:: TriggerCompactionRequest :: Rpc => Self :: Rpc ,
863
- }
864
- }
865
- }
866
-
867
836
/// A bit more weak version of `CachedAccounts` from the `tycho-rpc`.
868
837
struct CachedAccounts {
869
838
block_handle : BlockHandle ,
@@ -927,3 +896,68 @@ fn extend_signature_with_id(data: &[u8], signature_id: Option<i32>) -> Cow<'_, [
927
896
None => Cow :: Borrowed ( data) ,
928
897
}
929
898
}
899
+
900
+ #[ derive( Clone ) ]
901
+ struct ManualCompaction {
902
+ trigger : ManualTriggerTx ,
903
+ handle : AbortHandle ,
904
+ }
905
+
906
+ impl ManualCompaction {
907
+ pub fn new ( storage : Storage ) -> Self {
908
+ let ( compaction_trigger, manual_compaction_rx) =
909
+ watch:: channel ( None :: < proto:: TriggerCompactionRequest > ) ;
910
+
911
+ let watcher = tokio:: spawn ( Self :: watcher ( manual_compaction_rx, storage. clone ( ) ) ) ;
912
+
913
+ Self {
914
+ trigger : compaction_trigger,
915
+ handle : watcher. abort_handle ( ) ,
916
+ }
917
+ }
918
+
919
+ pub fn trigger_compaction ( & self , trigger : proto:: TriggerCompactionRequest ) {
920
+ self . trigger . send_replace ( Some ( trigger) ) ;
921
+ }
922
+
923
+ #[ tracing:: instrument( skip_all) ]
924
+ async fn watcher ( mut manual_rx : ManualTriggerRx , storage : Storage ) {
925
+ tracing:: info!( "manager started" ) ;
926
+ defer ! {
927
+ tracing:: info!( "manager stopped" ) ;
928
+ }
929
+
930
+ loop {
931
+ if manual_rx. changed ( ) . await . is_err ( ) {
932
+ break ;
933
+ }
934
+
935
+ let Some ( trigger) = * manual_rx. borrow_and_update ( ) else {
936
+ continue ;
937
+ } ;
938
+
939
+ match trigger {
940
+ proto:: TriggerCompactionRequest :: Base => {
941
+ storage. base_db ( ) . trigger_compaction ( ) . await ;
942
+ }
943
+ proto:: TriggerCompactionRequest :: Mempool => {
944
+ storage. mempool_db ( ) . trigger_compaction ( ) . await ;
945
+ }
946
+ proto:: TriggerCompactionRequest :: Rpc => {
947
+ if let Some ( rpc_db) = storage. rpc_db ( ) {
948
+ rpc_db. trigger_compaction ( ) . await ;
949
+ }
950
+ }
951
+ }
952
+ }
953
+ }
954
+ }
955
+
956
+ impl Drop for ManualCompaction {
957
+ fn drop ( & mut self ) {
958
+ self . handle . abort ( ) ;
959
+ }
960
+ }
961
+
962
+ type ManualTriggerTx = watch:: Sender < Option < proto:: TriggerCompactionRequest > > ;
963
+ type ManualTriggerRx = watch:: Receiver < Option < proto:: TriggerCompactionRequest > > ;
0 commit comments