Skip to content

Commit b2056a2

Browse files
committed
Fixed behavior for multiple queues.
1 parent 974194f commit b2056a2

File tree

6 files changed

+54
-31
lines changed

6 files changed

+54
-31
lines changed

.projen/deps.json

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.projenrc.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ const project = new typescript.TypeScriptProject({
33
defaultReleaseBranch: 'main',
44
name: 'aws-batch-simulator',
55
deps: [
6-
'@aws-cdk/aws-batch-alpha',
7-
'constructs',
86
],
97
description: 'A client-side tool to simulate the behavior of an AWS Batch application',
108
devDeps: ['aws-cdk-lib', 'constructs', 'ts-node'],
119
packageName: 'aws-batch-simulator',
1210
gitignore: ['.idea'],
13-
peerDeps: ['aws-cdk-lib'],
11+
peerDeps: ['aws-cdk-lib', '@aws-cdk/aws-batch-alpha', 'constructs'],
1412
releaseToNpm: true,
1513
repository: 'https://github.com/otaviomacedo/aws-batch-simulator.git',
1614
keywords: ['aws', 'batch', 'simulation', 'queueing', 'cdk', 'stochastic', 'markov'],

package.json

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/scheduling.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,10 +884,16 @@ export interface QueueMetrics {
884884
readonly size: number;
885885
}
886886

887+
export interface QueueHistory {
888+
id: string;
889+
metrics: QueueMetrics[];
890+
}
891+
887892
export interface JobQueueProps {
888893
readonly computeEnvironments: IComputeEnvironment[];
889894
readonly schedulingPolicy: ISchedulingPolicy;
890895
readonly eventLoop: EventLoop;
896+
readonly queueId: string;
891897
}
892898

893899
export class JobQueue implements IComputeEnvironmentListener {
@@ -898,12 +904,14 @@ export class JobQueue implements IComputeEnvironmentListener {
898904

899905
public readonly executionMetrics: ExecutionMetrics[] = [];
900906
public readonly queueMetrics: QueueMetrics[] = [];
907+
public readonly queueId: string;
901908

902909
constructor(props: JobQueueProps) {
903910
this.computeEnvironments = props.computeEnvironments;
904911
props.computeEnvironments.forEach(env => env.addListener(this));
905912
this.schedulingPolicy = props.schedulingPolicy;
906913
this.eventLoop = props.eventLoop;
914+
this.queueId = props.queueId;
907915
}
908916

909917
push(job: Job): void {

src/simulation.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import {
1414
IComputeEnvironment,
1515
ISchedulingPolicy,
1616
JobQueue,
17-
QueueMetrics,
17+
QueueHistory,
1818
} from './scheduling';
1919

20-
const NUMBER_OF_JOBS: number = 20000;
20+
const DEFAULT_NUMBER_OF_JOBS: number = 10000;
2121

2222
export interface StochasticModel {
2323
readonly interArrivalTimeDistribution: IDistribution;
@@ -120,8 +120,8 @@ export class JobGenerator {
120120

121121
private generateRandomJobs(): Job[] {
122122
let time = 0;
123-
const jobs: Job[] = new Array<Job>(NUMBER_OF_JOBS);
124-
for (let i = 0; i < NUMBER_OF_JOBS; i++) {
123+
const jobs: Job[] = new Array<Job>(DEFAULT_NUMBER_OF_JOBS);
124+
for (let i = 0; i < DEFAULT_NUMBER_OF_JOBS; i++) {
125125
const c = Math.floor(Math.random() * this.models.length);
126126
const jobDefinition: IJobDefinition = this.models[c].jobDefinition;
127127
const rng: RandomNumberGenerator = this.rngs[c];
@@ -154,8 +154,10 @@ export class JobGenerator {
154154
* Generates a random number from a geometric distribution
155155
*/
156156
function geometric(successProbability: number): number {
157+
if (successProbability === 1) return 1;
157158
return Math.ceil(Math.log(Math.random()) / Math.log(1 - successProbability));
158159
}
160+
159161
function validateConfigs(configs: StochasticModel[]) {
160162
// TODO test this
161163
if (configs.some(c => c.weightFactorProbabilities != null
@@ -200,7 +202,7 @@ interface SimulationResult {
200202
readonly timesByJobDefinition: Map<string, Histogram>;
201203
readonly meanTimeByShareIdentifier: Map<string, number>;
202204
readonly meanTimeByJobDefinition: Map<string, number>;
203-
readonly queueSize: QueueMetrics[];
205+
readonly queueHistories: QueueHistory[];
204206
}
205207

206208
export interface IBatchSimulator<M> {
@@ -291,7 +293,10 @@ export class Simulator {
291293
eventLoop.start();
292294

293295
const metrics: ExecutionMetrics[] = backlogs.flatMap(b => b.queue.executionMetrics);
294-
const queueSizeMetric: QueueMetrics[] = backlogs.flatMap(b => b.queue.queueMetrics);
296+
const queueHistories: QueueHistory[] = backlogs.map(b => ({
297+
id: b.queue.queueId,
298+
metrics: b.queue.queueMetrics,
299+
}));
295300
const map: Map<Job, number> = new Map(metrics.map(m => [m.job, m.time]));
296301

297302
const timesByShareIdentifier = this.aggregateByShareIdentifier(map);
@@ -313,7 +318,7 @@ export class Simulator {
313318
timesByJobDefinition,
314319
meanTimeByShareIdentifier,
315320
meanTimeByJobDefinition,
316-
queueSize: queueSizeMetric,
321+
queueHistories,
317322
});
318323
}
319324

@@ -364,6 +369,7 @@ class ConstructConverter {
364369
schedulingPolicy: this.convertSchedulingPolicy(queue.schedulingPolicy),
365370
computeEnvironments: queue.computeEnvironments.map(e => this.convertComputeEnvironment(e.computeEnvironment)),
366371
eventLoop: this.eventLoop,
372+
queueId: queue.node.path,
367373
});
368374
}
369375

@@ -433,6 +439,14 @@ export class SimulationReport {
433439
return result;
434440
};
435441

442+
const generateQueueDivs = () => {
443+
const result: string[] = [];
444+
this.simulationResult.queueHistories.forEach(history => {
445+
result.push(`<div id="q-${history.id}"></div>`);
446+
});
447+
return result;
448+
};
449+
436450
const generateCalls = () => {
437451
const calls: string[] = [];
438452
const header: [any, any][] = [['Time', '']];
@@ -442,20 +456,20 @@ export class SimulationReport {
442456
this.simulationResult.timesByJobDefinition.forEach((histogram, jobDefinition) => {
443457
calls.push(`drawChart('jd-${jobDefinition}', '${jobDefinition} (μ = ${this.simulationResult.meanTimeByJobDefinition.get(jobDefinition)})', ${JSON.stringify(header.concat(histogram.entries()))});`);
444458
});
459+
calls.push(...generateQueueHistories());
445460
return calls.join('\n');
446461
};
447462

448-
const generateQueueSize = () => {
449-
const header: [any, any][] = [['Time', 'Number of jobs']];
450-
const data: [number, number][] = this.simulationResult.queueSize
451-
.map(m => [m.time, m.size]);
452-
const sortedData: [number, number][] = data
453-
.sort((a, b) => a[0] - b[0])
454-
.filter((_, i) => i % 10 === 0);
455-
456-
return `drawChart('queue-size', 'Queue size', ${JSON.stringify(header.concat(sortedData))}, 'Line');`;
463+
const generateQueueHistories = () => {
464+
return this.simulationResult.queueHistories.map(history => {
465+
const header: [any, any][] = [['Time', 'Number of jobs']];
466+
const data: [number, number][] = history.metrics.map(p => ([p.time, p.size]));
467+
const sortedData: [number, number][] = data
468+
.sort((a, b) => a[0] - b[0])
469+
.filter((_, i) => i % 10 === 0);
470+
return `drawChart('q-${history.id}', '${history.id}', ${JSON.stringify(header.concat(sortedData))}, 'Line');`;
471+
});
457472
};
458-
459473
return `
460474
<html>
461475
<head>
@@ -482,7 +496,7 @@ export class SimulationReport {
482496
483497
function drawCharts() {
484498
${generateCalls()}
485-
${generateQueueSize()}
499+
486500
}
487501
</script>
488502
</head>
@@ -499,9 +513,9 @@ ${generateShareIdDivs().join('')}
499513
${generateJobDefinitionDivs().join('')}
500514
</div>
501515
502-
<h2>Queue size</h2>
516+
<h2>Queue histories</h2>
503517
<div bp="full-width">
504-
<div id="queue-size" />
518+
${generateQueueDivs().join('')}
505519
</div>
506520
507521
</body>

yarn.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)