Skip to content

Commit 2a6edfd

Browse files
committed
fix: fix Infinity speed that would happen when data was read on same ms
1 parent 27917b7 commit 2a6edfd

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

lib/speedometer.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module.exports = class Speedometer {
88
constructor(per) {
99
this.per = per;
1010
this.lasttime = null;
11+
this.lastsize = 0;
12+
this.lastlasttime = Date.now();
1113
this.total = 0;
1214
this.iteration = 0;
1315
this.speed = 0;
@@ -30,10 +32,20 @@ module.exports = class Speedometer {
3032
return;
3133
}
3234

33-
// Compare now to last time.
34-
const speed = Math.round((data.length / (now - this.lasttime)) *
35-
this.per);
36-
this.lasttime = now;
35+
let speed;
36+
if (now === this.lasttime) {
37+
// If more data is read on the same ms, aggregate it.
38+
this.lastsize += data.length;
39+
speed = this.lastsize / (now - this.lastlasttime);
40+
41+
} else {
42+
// Compare now to last time.
43+
speed = data.length / (now - this.lasttime);
44+
this.lastsize = data.length;
45+
this.lastlasttime = this.lasttime;
46+
this.lasttime = now;
47+
}
48+
speed = Math.round(speed * this.per);
3749

3850
// Get average speed.
3951
this.total += speed;

test/single-test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,35 @@ describe('Read when stream speed is sporadic', () => {
9393
});
9494
});
9595

96+
describe('Data is read on the same millisecond', () => {
97+
it('Speed is accurately calculated', (done) => {
98+
let clock = sinon.useFakeTimers();
99+
after(clock.restore);
100+
101+
const ss = new StreamSpeed();
102+
const rs = new MockStream();
103+
ss.add(rs);
104+
105+
const spy = sinon.spy();
106+
ss.on('speed', spy);
107+
108+
// Write at 2*400 bytes per second.
109+
setTimeout(() => {
110+
rs.write(Buffer.alloc(400), () => {
111+
rs.write(Buffer.alloc(400), () => {
112+
process.nextTick(rs.end.bind(rs));
113+
});
114+
});
115+
}, 100);
116+
process.nextTick(clock.tick.bind(clock, 100));
117+
118+
rs.on('end', () => {
119+
assert.ok(spy.called);
120+
done();
121+
});
122+
});
123+
});
124+
96125
describe('Stream being monitored has an error', () => {
97126
it('Stream gets removed', () => {
98127
const ss = new StreamSpeed();

0 commit comments

Comments
 (0)