@@ -10,7 +10,9 @@ use nodedb_cluster::wire::VShardEnvelope;
1010
1111use crate :: control:: cluster:: calvin:: scheduler:: metrics:: SchedulerMetrics ;
1212use crate :: control:: cluster:: calvin:: scheduler:: read_last_applied_epoch;
13- use crate :: control:: cluster:: calvin:: { ReadResultEvent , Scheduler , SchedulerConfig } ;
13+ use crate :: control:: cluster:: calvin:: {
14+ ReadResultEvent , Scheduler , SchedulerConfig , SchedulerParams ,
15+ } ;
1416use crate :: control:: cluster:: handle:: ClusterHandle ;
1517use crate :: control:: state:: SharedState ;
1618
@@ -91,6 +93,17 @@ fn hosted_vshards(routing: &RwLock<nodedb_cluster::RoutingTable>, node_id: u64)
9193 vshards
9294}
9395
96+ /// Parameters for [`reconcile_vshard_schedulers`].
97+ struct ReconcileSchedulersParams < ' a > {
98+ node_id : u64 ,
99+ routing : & ' a Arc < RwLock < nodedb_cluster:: RoutingTable > > ,
100+ shared : & ' a Arc < SharedState > ,
101+ raft_loop_handle : & ' a Arc < Mutex < nodedb_cluster:: multi_raft:: MultiRaft > > ,
102+ sequencer_state_machine : & ' a Arc < Mutex < SequencerStateMachine > > ,
103+ calvin_read_result_senders : & ' a ReadResultSenders ,
104+ scheduler_config : & ' a SchedulerConfig ,
105+ }
106+
94107/// Idempotently ensure a Calvin `Scheduler` is running for every vShard this
95108/// node currently hosts.
96109///
@@ -103,16 +116,17 @@ fn hosted_vshards(routing: &RwLock<nodedb_cluster::RoutingTable>, node_id: u64)
103116/// left this node. vShard removal happens via migration / decommission, which
104117/// own their own teardown path; wiring scheduler removal into that lifecycle is
105118/// tracked as a separate follow-up.
106- #[ allow( clippy:: too_many_arguments) ]
107- fn reconcile_vshard_schedulers (
108- node_id : u64 ,
109- routing : & Arc < RwLock < nodedb_cluster:: RoutingTable > > ,
110- shared : & Arc < SharedState > ,
111- raft_loop_handle : & Arc < Mutex < nodedb_cluster:: multi_raft:: MultiRaft > > ,
112- sequencer_state_machine : & Arc < Mutex < SequencerStateMachine > > ,
113- calvin_read_result_senders : & ReadResultSenders ,
114- scheduler_config : & SchedulerConfig ,
115- ) -> crate :: Result < usize > {
119+ fn reconcile_vshard_schedulers ( params : ReconcileSchedulersParams < ' _ > ) -> crate :: Result < usize > {
120+ let ReconcileSchedulersParams {
121+ node_id,
122+ routing,
123+ shared,
124+ raft_loop_handle,
125+ sequencer_state_machine,
126+ calvin_read_result_senders,
127+ scheduler_config,
128+ } = params;
129+
116130 let mut spawned = 0usize ;
117131 for vshard_id in hosted_vshards ( routing, node_id) {
118132 // Already-served vShards keep their running scheduler untouched.
@@ -139,17 +153,17 @@ fn reconcile_vshard_schedulers(
139153 . unwrap_or_else ( |p| p. into_inner ( ) )
140154 . insert ( vshard_id, read_result_tx) ;
141155
142- let scheduler = Scheduler :: new (
156+ let scheduler = Scheduler :: new ( SchedulerParams {
143157 vshard_id,
144- sequenced_rx,
145- Arc :: clone ( shared) ,
146- raft_loop_handle. clone ( ) ,
158+ receiver : sequenced_rx,
159+ shared : Arc :: clone ( shared) ,
160+ multi_raft : raft_loop_handle. clone ( ) ,
147161 last_applied_epoch,
148- last_applied_epoch,
149- scheduler_config. clone ( ) ,
150- SchedulerMetrics :: new ( ) ,
162+ rebuild_target_epoch : last_applied_epoch,
163+ config : scheduler_config. clone ( ) ,
164+ metrics : SchedulerMetrics :: new ( ) ,
151165 read_result_rx,
152- ) ;
166+ } ) ;
153167 let shutdown = shared. shutdown . subscribe ( ) ;
154168 tokio:: spawn ( async move {
155169 scheduler. run ( shutdown) . await ;
@@ -159,6 +173,16 @@ fn reconcile_vshard_schedulers(
159173 Ok ( spawned)
160174}
161175
176+ /// Parameters for [`spawn_vshard_schedulers`].
177+ pub ( super ) struct SpawnVshardSchedulersParams < ' a > {
178+ pub ( super ) handle : & ' a ClusterHandle ,
179+ pub ( super ) shared : & ' a Arc < SharedState > ,
180+ pub ( super ) raft_loop_handle : Arc < Mutex < nodedb_cluster:: multi_raft:: MultiRaft > > ,
181+ pub ( super ) sequencer_state_machine : & ' a Arc < Mutex < SequencerStateMachine > > ,
182+ pub ( super ) calvin_read_result_senders : & ' a ReadResultSenders ,
183+ pub ( super ) scheduler_config : & ' a SchedulerConfig ,
184+ }
185+
162186/// Spawn Calvin `Scheduler` tasks for this node's vShards and keep the set in
163187/// sync with cluster membership.
164188///
@@ -174,28 +198,31 @@ fn reconcile_vshard_schedulers(
174198/// (covers the bootstrap node, which already sees its membership) and then
175199/// spawns a background task that re-reconciles on a short interval until
176200/// shutdown. Reconcile is idempotent and add-only.
177- #[ allow( clippy:: too_many_arguments) ]
178201pub ( super ) fn spawn_vshard_schedulers (
179- handle : & ClusterHandle ,
180- shared : & Arc < SharedState > ,
181- raft_loop_handle : Arc < Mutex < nodedb_cluster:: multi_raft:: MultiRaft > > ,
182- sequencer_state_machine : & Arc < Mutex < SequencerStateMachine > > ,
183- calvin_read_result_senders : & ReadResultSenders ,
184- scheduler_config : & SchedulerConfig ,
202+ params : SpawnVshardSchedulersParams < ' _ > ,
185203) -> crate :: Result < ( ) > {
204+ let SpawnVshardSchedulersParams {
205+ handle,
206+ shared,
207+ raft_loop_handle,
208+ sequencer_state_machine,
209+ calvin_read_result_senders,
210+ scheduler_config,
211+ } = params;
212+
186213 let node_id = handle. node_id ;
187214 let routing = Arc :: clone ( & handle. routing ) ;
188215
189216 // Initial reconcile: schedulers for vShards this node already knows it hosts.
190- reconcile_vshard_schedulers (
217+ reconcile_vshard_schedulers ( ReconcileSchedulersParams {
191218 node_id,
192- & routing,
219+ routing : & routing,
193220 shared,
194- & raft_loop_handle,
221+ raft_loop_handle : & raft_loop_handle,
195222 sequencer_state_machine,
196223 calvin_read_result_senders,
197224 scheduler_config,
198- ) ?;
225+ } ) ?;
199226
200227 // Background reconcile: pick up vShards whose membership lands after startup
201228 // (joiner admission) or shifts later (rebalancing). The routing table has no
@@ -215,15 +242,15 @@ pub(super) fn spawn_vshard_schedulers(
215242 biased;
216243 _ = shutdown. wait_cancelled( ) => break ,
217244 _ = tick. tick( ) => {
218- if let Err ( e) = reconcile_vshard_schedulers(
245+ if let Err ( e) = reconcile_vshard_schedulers( ReconcileSchedulersParams {
219246 node_id,
220- & routing,
221- & shared_task,
222- & raft_loop_handle,
223- & sm_task,
224- & rr_task,
225- & cfg_task,
226- ) {
247+ routing : & routing,
248+ shared : & shared_task,
249+ raft_loop_handle : & raft_loop_handle,
250+ sequencer_state_machine : & sm_task,
251+ calvin_read_result_senders : & rr_task,
252+ scheduler_config : & cfg_task,
253+ } ) {
227254 tracing:: warn!( node_id, error = %e, "calvin scheduler reconcile pass failed" ) ;
228255 }
229256 }
0 commit comments