-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
scheduling-policy.ts
245 lines (226 loc) · 9.18 KB
/
scheduling-policy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
import { Construct } from 'constructs';
import { CfnSchedulingPolicy } from './batch.generated';
import { ArnFormat, Duration, IResource, Lazy, Resource, Stack } from '../../core';
/**
* Represents a Scheduling Policy. Scheduling Policies tell the Batch
* Job Scheduler how to schedule incoming jobs.
*/
export interface ISchedulingPolicy extends IResource {
/**
* The name of this scheduling policy
*
* @attribute
*/
readonly schedulingPolicyName: string;
/**
* The arn of this scheduling policy
*
* @attribute
*/
readonly schedulingPolicyArn: string;
}
/**
* Props to configure a SchedulingPolicy
*/
interface SchedulingPolicyProps {
/**
* The name of this SchedulingPolicy
*
* @default - generated by CloudFormation
*/
readonly schedulingPolicyName?: string;
}
/**
* @internal
*/
export abstract class SchedulingPolicyBase extends Resource implements ISchedulingPolicy {
public abstract readonly schedulingPolicyName: string;
public abstract readonly schedulingPolicyArn: string;
constructor(scope: Construct, id: string, props?: SchedulingPolicyProps) {
super(scope, id, {
physicalName: props?.schedulingPolicyName,
});
}
}
/**
* Represents a group of Job Definitions. All Job Definitions that
* declare a share identifier will be considered members of the Share
* defined by that share identifier.
*
* The Scheduler divides the maximum available vCPUs of the ComputeEnvironment
* among Jobs in the Queue based on their shareIdentifier and the weightFactor
* associated with that shareIdentifier.
*/
export interface Share {
/**
* The identifier of this Share. All jobs that specify this share identifier
* when submitted to the queue will be considered as part of this Share.
*/
readonly shareIdentifier: string;
/**
* The weight factor given to this Share. The Scheduler decides which jobs to put in the Compute Environment
* such that the following ratio is equal for each job:
*
* `sharevCpu / weightFactor`,
*
* where `sharevCpu` is the total amount of vCPU given to that particular share; that is,
* the sum of the vCPU of each job currently in the Compute Environment for that share.
*
* See the readme of this module for a detailed example that shows how these are used,
* how it relates to `computeReservation`, and how `shareDecay` affects these calculations.
*/
readonly weightFactor: number;
}
/**
* Represents a Fairshare Scheduling Policy. Instructs the scheduler
* to allocate ComputeEnvironment vCPUs based on Job shareIdentifiers.
*
* The Faireshare Scheduling Policy ensures that each share gets a certain amount of vCPUs.
* It does this by deciding how many Jobs of each share to schedule *relative to how many jobs of
* each share are currently being executed by the ComputeEnvironment*. The weight factors associated with
* each share determine the ratio of vCPUs allocated; see the readme for a more in-depth discussion of
* fairshare policies.
*/
export interface IFairshareSchedulingPolicy extends ISchedulingPolicy {
/**
* Used to calculate the percentage of the maximum available vCPU to reserve for share identifiers not present in the Queue.
*
* The percentage reserved is defined by the Scheduler as:
* `(computeReservation/100)^ActiveFairShares` where `ActiveFairShares` is the number of active fair share identifiers.
*
* For example, a computeReservation value of 50 indicates that AWS Batch reserves 50% of the
* maximum available vCPU if there's only one fair share identifier.
* It reserves 25% if there are two fair share identifiers.
* It reserves 12.5% if there are three fair share identifiers.
*
* A computeReservation value of 25 indicates that AWS Batch should reserve 25% of the
* maximum available vCPU if there's only one fair share identifier,
* 6.25% if there are two fair share identifiers,
* and 1.56% if there are three fair share identifiers.
*
* @default - no vCPU is reserved
*/
readonly computeReservation?: number;
/**
* The amount of time to use to measure the usage of each job.
* The usage is used to calculate a fair share percentage for each fair share identifier currently in the Queue.
* A value of zero (0) indicates that only current usage is measured.
* The decay is linear and gives preference to newer jobs.
*
* The maximum supported value is 604800 seconds (1 week).
*
* @default - 0: only the current job usage is considered
*/
readonly shareDecay?: Duration;
/**
* The shares that this Scheduling Policy applies to.
* *Note*: It is possible to submit Jobs to the queue with Share Identifiers that
* are not recognized by the Scheduling Policy.
*/
readonly shares: Share[];
}
/**
* Fairshare SchedulingPolicy configuration
*/
export interface FairshareSchedulingPolicyProps extends SchedulingPolicyProps {
/**
* Used to calculate the percentage of the maximum available vCPU to reserve for share identifiers not present in the Queue.
*
* The percentage reserved is defined by the Scheduler as:
* `(computeReservation/100)^ActiveFairShares` where `ActiveFairShares` is the number of active fair share identifiers.
*
* For example, a computeReservation value of 50 indicates that AWS Batch reserves 50% of the
* maximum available vCPU if there's only one fair share identifier.
* It reserves 25% if there are two fair share identifiers.
* It reserves 12.5% if there are three fair share identifiers.
*
* A computeReservation value of 25 indicates that AWS Batch should reserve 25% of the
* maximum available vCPU if there's only one fair share identifier,
* 6.25% if there are two fair share identifiers,
* and 1.56% if there are three fair share identifiers.
*
* @default - no vCPU is reserved
*/
readonly computeReservation?: number;
/**
* The amount of time to use to measure the usage of each job.
* The usage is used to calculate a fair share percentage for each fair share identifier currently in the Queue.
* A value of zero (0) indicates that only current usage is measured.
* The decay is linear and gives preference to newer jobs.
*
* The maximum supported value is 604800 seconds (1 week).
*
* @default - 0: only the current job usage is considered
*/
readonly shareDecay?: Duration;
/**
* The shares that this Scheduling Policy applies to.
* *Note*: It is possible to submit Jobs to the queue with Share Identifiers that
* are not recognized by the Scheduling Policy.
*
* @default - no shares
*/
readonly shares?: Share[];
}
/**
* Represents a Fairshare Scheduling Policy. Instructs the scheduler
* to allocate ComputeEnvironment vCPUs based on Job shareIdentifiers.
*
* The Faireshare Scheduling Policy ensures that each share gets a certain amount of vCPUs.
* The scheduler does this by deciding how many Jobs of each share to schedule *relative to how many jobs of
* each share are currently being executed by the ComputeEnvironment*. The weight factors associated with
* each share determine the ratio of vCPUs allocated; see the readme for a more in-depth discussion of
* fairshare policies.
*
* @resource AWS::Batch::SchedulingPolicy
*/
export class FairshareSchedulingPolicy extends SchedulingPolicyBase implements IFairshareSchedulingPolicy {
/**
* Reference an exisiting Scheduling Policy by its ARN
*/
public static fromFairshareSchedulingPolicyArn(scope: Construct, id: string, fairshareSchedulingPolicyArn: string): IFairshareSchedulingPolicy {
const stack = Stack.of(scope);
class Import extends SchedulingPolicyBase implements IFairshareSchedulingPolicy {
public readonly schedulingPolicyArn = fairshareSchedulingPolicyArn;
public readonly schedulingPolicyName = stack.splitArn(fairshareSchedulingPolicyArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName!;
public readonly shares = [];
}
return new Import(scope, id);
}
public readonly computeReservation?: number;
public readonly shareDecay?: Duration;
public readonly shares: Share[];
public readonly schedulingPolicyArn: string;
public readonly schedulingPolicyName: string;
constructor(scope: Construct, id: string, props?: FairshareSchedulingPolicyProps) {
super(scope, id, props);
this.computeReservation = props?.computeReservation;
this.shareDecay = props?.shareDecay;
this.shares = props?.shares ?? [];
const resource = new CfnSchedulingPolicy(this, 'Resource', {
fairsharePolicy: {
computeReservation: this.computeReservation,
shareDecaySeconds: this.shareDecay?.toSeconds(),
shareDistribution: Lazy.any({
produce: () => this.shares?.map((share) => ({
shareIdentifier: share.shareIdentifier,
weightFactor: share.weightFactor,
})),
}),
},
name: props?.schedulingPolicyName,
});
this.schedulingPolicyArn = this.getResourceArnAttribute(resource.attrArn, {
service: 'batch',
resource: 'scheduling-policy',
resourceName: this.physicalName,
});
this.schedulingPolicyName = this.getResourceNameAttribute(resource.ref);
}
/**
* Add a share this to this Fairshare SchedulingPolicy
*/
public addShare(share: Share) {
this.shares.push(share);
}
}