-
Notifications
You must be signed in to change notification settings - Fork 7
/
locust.js
81 lines (61 loc) · 1.82 KB
/
locust.js
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
const uuid = require('uuid/v4');
const logger = require('./logger');
const { TaskSet } = require('./task-set');
const { RequestError } = require('./error');
const STATES = {
IDLE: 'idle',
STOPPED: 'stopped',
RUNNING: 'running'
};
class Locust {
constructor() {
this.taskSet = null;
this.state = STATES.IDLE;
this.locustId = uuid();
}
async start(statsAggregator) {
this.log('Starting locust');
if (!(this.taskSet instanceof TaskSet)) {
this.log('Locust.taskSet is not define');
return;
}
// Generate an array of tasks to ensure ensure correct tasks weight
const weights = this.taskSet.tasks.map(task => task.weight || 1);
const weightSum = weights.reduce((sum, weight) => sum + weight, 0);
const amountTasks = Math.max(...weights) * weightSum;
let tasks = [];
for (const { task, weight } of this.taskSet.tasks) {
const rate = (weight || 1) / weightSum;
const repeatTask = Math.trunc(amountTasks * rate);
tasks = tasks.concat(Array.from({ length: repeatTask }, () => task));
}
this.taskSet.statsAggregator = statsAggregator;
await this.taskSet.before();
if (!tasks.length) return;
while (true) {
for (const task of tasks) {
if (this.state === STATES.STOPPED) {
await this.taskSet.after();
return;
}
await this.taskSet.beforeEach();
try {
await task();
} catch (error) {
if (!(error instanceof RequestError)) {
logger.error('Unexpected error occurred', error);
}
}
await this.taskSet.afterEach();
}
}
}
stop() {
this.log('Stopping locust...');
this.state = STATES.STOPPED;
}
log(message) {
logger.info(`${this.locustId} | ${message}`);
}
}
module.exports = { Locust, TaskSet };