Skip to content

Commit 4e379f5

Browse files
juanig1hassy
authored andcommitted
fix(ramp): handle 1s periods properly
- Take into account arrival adjustment by worker - Fix low arrival rate causing arrival periodTick to be Infinity
1 parent 69ed6eb commit 4e379f5

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

packages/core/lib/phases.js

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,33 +107,36 @@ function createRamp(spec, ee) {
107107

108108
const difference = rampTo - arrivalRate;
109109
const periods = duration;
110-
debug(`worker ${worker} totalWorkers ${totalWorkers} arrivalRate ${arrivalRate} rampTo ${rampTo} difference ${difference} periods ${periods}`);
110+
debug(
111+
`worker ${worker} totalWorkers ${totalWorkers} arrivalRate ${arrivalRate} rampTo ${rampTo} difference ${difference} periods ${periods}`
112+
);
111113

112114
const periodArrivals = [];
113115
const periodTick = [];
114116
// if there is only one peridod we generate mean arrivals
115117
if (periods === 1) {
116-
periodArrivals[0] = Math.floor((rampTo + arrivalRate) / 2);
117-
periodTick[0] = 1000 / periodArrivals;
118+
const rawPeriodArrivals = (rampTo + arrivalRate) / 2;
119+
periodArrivals[0] = adjustArrivalsByWorker(
120+
rawPeriodArrivals,
121+
totalWorkers,
122+
worker
123+
);
118124
} else {
119125
// for each period we calculate the corresponding arrivals:
120126
// knowing that arrivals(0) = arrivalRate and arrivals(duration -1) = rampTo
121127
// then: arrivals(t) = difference / (duration-1) * t + arrivalRate
122128
for (let i = 0; i < periods; i++) {
123129
const rawPeriodArrivals = (difference / (duration - 1)) * i + arrivalRate;
124130

125-
// We use the floor of the expected arrivals, then we add up all decimal digits
126-
// and evaluate if one or more workers should bump their arrivalRate.
127-
periodArrivals[i] = Math.floor(rawPeriodArrivals);
128-
129-
// Think of fractionalPart * workers as the amount of arrivals that could not be
130-
// shared evenly across all workers.
131-
if (Math.round((rawPeriodArrivals % 1) * totalWorkers) >= worker) {
132-
periodArrivals[i] = periodArrivals[i] + 1;
133-
}
131+
// take into account added decimals and bump worker arrivals if needed
132+
periodArrivals[i] = adjustArrivalsByWorker(
133+
rawPeriodArrivals,
134+
totalWorkers,
135+
worker
136+
);
134137

135138
// Needed ticks to get to periodArrivals in 1000ms
136-
periodTick[i] = periodArrivals[i] > 0 ? Math.floor(1000 / periodArrivals[i]) : 1000;
139+
periodTick[i] = Math.min(Math.floor(1000 / periodArrivals[i]), 1000);
137140
}
138141
}
139142

@@ -148,9 +151,24 @@ function createRamp(spec, ee) {
148151
}
149152

150153
ee.emit('phaseCompleted', spec);
154+
};
155+
156+
function adjustArrivalsByWorker(rawPeriodArrivals, totalWorkers, worker) {
157+
// We use the floor of the expected arrivals, then we add up all decimal digits
158+
// and evaluate if one or more workers should bump their arrivalRate.
159+
let arrivals = Math.floor(rawPeriodArrivals);
160+
161+
// Think of fractionalPart * workers as the amount of arrivals that could not be
162+
// shared evenly across all workers.
163+
if (Math.round((rawPeriodArrivals % 1) * totalWorkers) >= worker) {
164+
arrivals = arrivals + 1;
165+
}
166+
return arrivals;
151167
}
152168

153169
function ticker(currentPeriod) {
170+
// ensure we don't go past 1s
171+
const delay = Math.min(periodTick[currentPeriod], 1000);
154172
let currentArrivals = 0;
155173
let arrivalTimer = driftless.setDriftlessInterval(function arrivals() {
156174
if (currentArrivals < periodArrivals[currentPeriod]) {
@@ -160,7 +178,7 @@ function createRamp(spec, ee) {
160178
currentPeriod++;
161179
driftless.clearDriftless(arrivalTimer);
162180
}
163-
}, periodTick[currentPeriod]);
181+
}, delay);
164182
return;
165183
}
166184
}

0 commit comments

Comments
 (0)