1- use crate :: Map ;
21use crate :: control:: { NewWorkerAllocationResponse , WorkerTypeQuery } ;
32use crate :: gateway:: MultiNodeAllocationResponse ;
43use crate :: internal:: server:: core:: Core ;
54use crate :: internal:: server:: task:: Task ;
65use crate :: internal:: server:: workerload:: { WorkerLoad , WorkerResources } ;
7- use crate :: resources:: ResourceRequestVariants ;
8- use smallvec:: smallvec;
96use std:: time:: Duration ;
107
118struct WorkerTypeState {
9+ partial : bool ,
1210 loads : Vec < WorkerLoad > ,
1311 w_resources : WorkerResources ,
1412 time_limit : Option < Duration > ,
@@ -19,46 +17,43 @@ struct WorkerTypeState {
1917pub ( crate ) fn compute_new_worker_query (
2018 core : & mut Core ,
2119 queries : & [ WorkerTypeQuery ] ,
22- collect_leftovers : bool ,
2320) -> NewWorkerAllocationResponse {
2421 log:: debug!( "Compute new worker query: query = {queries:?}" ) ;
2522
2623 // Scheduler has to be performed before the query, so there should be no ready_to_assign tasks
2724 assert ! ( core. sn_ready_to_assign( ) . is_empty( ) || !core. has_workers( ) ) ;
2825
29- let add_task = |new_loads : & mut [ WorkerTypeState ] ,
30- task : & Task ,
31- leftovers : & mut Map < ResourceRequestVariants , u32 > | {
26+ let add_task = |new_loads : & mut [ WorkerTypeState ] , task : & Task | {
3227 let request = & task. configuration . resources ;
3328 for ws in new_loads. iter_mut ( ) {
34- if let Some ( time_limit) = ws. time_limit {
35- if !ws
36- . w_resources
37- . is_capable_to_run_with ( request, |rq| rq. min_time ( ) <= time_limit)
38- {
29+ if !ws. partial {
30+ if !ws. w_resources . is_capable_to_run_with ( request, |rq| {
31+ ws. time_limit . is_none_or ( |t| rq. min_time ( ) <= t)
32+ } ) {
3933 continue ;
4034 }
41- } else if !ws. w_resources . is_capable_to_run ( request) {
42- continue ;
43- }
44- for load in ws. loads . iter_mut ( ) {
45- if load. have_immediate_resources_for_rqv ( request, & ws. w_resources ) {
35+ for load in ws. loads . iter_mut ( ) {
36+ if load. have_immediate_resources_for_rqv ( request, & ws. w_resources ) {
37+ load. add_request ( task. id , request, & ws. w_resources ) ;
38+ return ;
39+ }
40+ }
41+ if ws. loads . len ( ) < ws. max as usize {
42+ let mut load = WorkerLoad :: new ( & ws. w_resources ) ;
4643 load. add_request ( task. id , request, & ws. w_resources ) ;
44+ ws. loads . push ( load) ;
4745 return ;
4846 }
49- }
50- if ws. loads . len ( ) < ws. max as usize {
51- let mut load = WorkerLoad :: new ( & ws. w_resources ) ;
52- load. add_request ( task. id , request, & ws. w_resources ) ;
53- ws. loads . push ( load) ;
54- return ;
55- }
56- }
57- if collect_leftovers {
58- if let Some ( count) = leftovers. get_mut ( request) {
59- * count += 1 ;
6047 } else {
61- leftovers. insert ( request. clone ( ) , 1 ) ;
48+ if !ws. w_resources . is_lowerbound_for ( request, |rq| {
49+ ws. time_limit . is_none_or ( |t| rq. min_time ( ) <= t)
50+ } ) {
51+ continue ;
52+ }
53+ if ws. loads . is_empty ( ) {
54+ let load = WorkerLoad :: new ( & ws. w_resources ) ;
55+ ws. loads . push ( load) ;
56+ }
6257 }
6358 }
6459 } ;
@@ -74,14 +69,14 @@ pub(crate) fn compute_new_worker_query(
7469 let mut new_loads: Vec < _ > = queries
7570 . iter ( )
7671 . map ( |q| WorkerTypeState {
72+ partial : q. partial ,
7773 loads : Vec :: new ( ) ,
7874 w_resources : WorkerResources :: from_description ( & q. descriptor , & resource_map) ,
7975 time_limit : q. time_limit ,
8076 max : q. max_sn_workers ,
8177 } )
8278 . collect ( ) ;
8379
84- let mut leftovers = Map :: new ( ) ;
8580 for worker in core. get_workers ( ) {
8681 let mut load = WorkerLoad :: new ( & worker. resources ) ;
8782 for task_id in worker. sn_tasks ( ) {
@@ -93,12 +88,12 @@ pub(crate) fn compute_new_worker_query(
9388 load. add_request ( task. id , request, & worker. resources ) ;
9489 continue ;
9590 }
96- add_task ( & mut new_loads, task, & mut leftovers ) ;
91+ add_task ( & mut new_loads, task) ;
9792 }
9893 }
9994 for task_id in core. sleeping_sn_tasks ( ) {
10095 let task = core. get_task ( * task_id) ;
101- add_task ( & mut new_loads, task, & mut leftovers ) ;
96+ add_task ( & mut new_loads, task) ;
10297 }
10398
10499 // `compute_new_worker_query` should be called immediately after scheduling was performed,
@@ -107,13 +102,16 @@ pub(crate) fn compute_new_worker_query(
107102 // postponing ready_to_assign. So we have to look also into this array
108103 for task_id in core. sn_ready_to_assign ( ) {
109104 let task = core. get_task ( * task_id) ;
110- add_task ( & mut new_loads, task, & mut leftovers ) ;
105+ add_task ( & mut new_loads, task) ;
111106 }
112107
113108 let single_node_allocations = new_loads
114109 . iter ( )
115110 . zip ( queries. iter ( ) )
116111 . map ( |( ws, q) | {
112+ if ws. partial {
113+ return ws. loads . len ( ) ;
114+ }
117115 ws. loads
118116 . iter ( )
119117 . map ( |load| {
@@ -148,28 +146,13 @@ pub(crate) fn compute_new_worker_query(
148146 None
149147 }
150148 } ) ;
151- if collect_leftovers && result. is_none ( ) {
152- let request = ResourceRequestVariants :: new ( smallvec ! [ rq. clone( ) ] ) ;
153- leftovers. insert ( request, count) ;
154- }
155149 result
156150 } )
157151 . collect ( ) ;
158152 multi_node_allocations. sort_unstable_by_key ( |x| ( x. worker_type , x. worker_per_allocation ) ) ;
159153
160- let leftovers = if collect_leftovers {
161- let resource_map = core. create_resource_map ( ) ;
162- leftovers
163- . into_iter ( )
164- . map ( |( v, s) | ( v. to_gateway ( & resource_map) , s) )
165- . collect ( )
166- } else {
167- Vec :: new ( )
168- } ;
169-
170154 NewWorkerAllocationResponse {
171155 single_node_workers_per_query : single_node_allocations,
172- leftovers,
173156 multi_node_allocations,
174157 }
175158}
0 commit comments