88 "context"
99 "errors"
1010 "sync"
11+ "sync/atomic"
1112 "time"
1213
1314 "github.com/hashicorp/go-hclog"
@@ -24,7 +25,7 @@ type DynamicPriorityQueue struct {
2425 // tenants is used to keep track of cluster usage for this queue.
2526 // When workloads are placed or the configured interval is passed,
2627 // cluster usage is updated for the workloads of each tenant.
27- tenants map [TenantID ]Tenant
28+ tenants map [TenantID ]* Tenant
2829
2930 // queue is the main datastructure that contains all pending workloads
3031 //
@@ -49,25 +50,27 @@ type DynamicPriorityQueue struct {
4950 // totalUsage is the sum of all tenant usages
5051 totalUsage int
5152
53+ tenantType structs.BatchQueueTenant
54+
55+ metadataKey string
56+
5257 // conf contains user configurations for tuning the behavior of the queue
53- conf * DynamicPriorityConfig
58+ conf * structs. DynamicQueueConfig
5459
5560 // evalBroker is the injected broker for passing an evaluation
5661 // on to be scheduled by Nomad
57- evalBroker Queue
62+ evalBroker Broker
63+
64+ // enabled tracks whether the server running the batch job queue is the leader
65+ // so should process evaluations
66+ enabled atomic.Bool
5867
5968 // state is the in-memory state store used for both reconciling tenant
6069 // workload usages, and polling submitted evaluations for placement
6170 state * state.StateStore
6271 logger hclog.Logger
6372}
6473
65- type DynamicPriorityConfig struct {
66- TenantType string
67- MetadataKey string
68- CalcInterval time.Duration
69- }
70-
7174type Tenant struct {
7275 tid TenantID
7376 workloads map [string ]* Workload
@@ -87,33 +90,46 @@ func (w *Workload) calculatePriority(_ int64) {
8790 // unimplemented
8891}
8992
90- func NewDynamicPriorityQueue (state * state. StateStore , broker Queue , conf * DynamicPriorityConfig , logger hclog.Logger ) * DynamicPriorityQueue {
93+ func NewDynamicPriorityQueue (broker Broker , qconf * structs. BatchQueue , conf * structs. DynamicQueueConfig , logger hclog.Logger ) * DynamicPriorityQueue {
9194 return & DynamicPriorityQueue {
92- tenants : map [TenantID ]Tenant {},
93- queue : WorkloadQueue {},
94- state : state ,
95- enqueueCh : make (chan * Workload , 8096 ),
96- evalBroker : broker ,
97- qMux : sync.Mutex {},
98- qNotify : make (chan struct {}, 1 ),
99- conf : conf ,
100- logger : logger .Named ("Dynamic Priority Queue" ),
95+ tenants : make (map [TenantID ]* Tenant ),
96+ queue : WorkloadQueue {},
97+ enqueueCh : make (chan * Workload , 8192 ),
98+ evalBroker : broker ,
99+ qMux : sync.Mutex {},
100+ qNotify : make (chan struct {}, 1 ),
101+ tenantType : qconf .TenantType ,
102+ metadataKey : qconf .MetadataKey ,
103+ conf : conf ,
104+ logger : logger .Named ("Dynamic Priority Queue" ),
105+ totalUsage : 0 ,
101106 }
102107}
103108
104- func (d * DynamicPriorityQueue ) Start (ctx context.Context ) {
105- // rebuild internal state from statestore, unimplemented
106-
109+ func (d * DynamicPriorityQueue ) Start (ctx context.Context ) error {
107110 go d .runProducer (ctx )
108111 go d .runConsumer (ctx )
112+
113+ return nil
114+ }
115+
116+ func (d * DynamicPriorityQueue ) SetEnabled (val bool , state * state.StateStore ) {
117+ // rebuild internal state from statestore, unimplemented
118+ d .state = state
119+ d .enabled .Store (val )
109120}
110121
111122// Enqueue is the method used to put evaluations on the queue.
112123// It generates a workload with an empty priority, appends it
113124// to an internal channel to be processed and added to the actual
114125// heap container.
115126func (d * DynamicPriorityQueue ) Enqueue (e * structs.Evaluation ) {
127+ if ! d .enabled .Load () {
128+ return
129+ }
130+
116131 w := d .generateWorkload (e )
132+
117133 // in the event of an empty workload, just pass eval to eval broker
118134 if w == nil {
119135 d .evalBroker .Enqueue (e )
@@ -143,6 +159,10 @@ func (d *DynamicPriorityQueue) runProducer(ctx context.Context) {
143159 default :
144160 }
145161 case <- time .After (d .conf .CalcInterval ):
162+ if ! d .enabled .Load () {
163+ continue
164+ }
165+
146166 d .qMux .Lock ()
147167 d .calculatePriorities (time .Now ().UnixNano ())
148168 heap .Init (& d .queue )
@@ -199,11 +219,11 @@ func (d *DynamicPriorityQueue) generateWorkload(e *structs.Evaluation) *Workload
199219 }
200220
201221 tid := ""
202- switch d .conf . TenantType {
222+ switch d .tenantType {
203223 case "namespace" :
204224 tid = job .Namespace
205225 case "metadata" :
206- tenantID , ok := job .Meta [d .conf . MetadataKey ]
226+ tenantID , ok := job .Meta [d .metadataKey ]
207227 if ! ok {
208228 return nil
209229 }
0 commit comments