mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
fix(SimpleIdentifyThrottler): don't sleep negative amounts (#10669)
* fix(SimpleIdentifyThrottler): don't sleep negative amounts * fix: test
This commit is contained in:
committed by
GitHub
parent
b81ad113a0
commit
b854c7b979
@@ -1,33 +1,58 @@
|
|||||||
// @ts-nocheck
|
import * as timers from 'node:timers/promises';
|
||||||
import { setTimeout as sleep } from 'node:timers/promises';
|
import { expect, test, vi, beforeEach, afterEach } from 'vitest';
|
||||||
import { expect, test, vi } from 'vitest';
|
|
||||||
import { SimpleIdentifyThrottler } from '../../src/index.js';
|
import { SimpleIdentifyThrottler } from '../../src/index.js';
|
||||||
|
|
||||||
vi.mock('node:timers/promises', () => ({
|
vi.mock('node:timers/promises', () => ({
|
||||||
setTimeout: vi.fn(),
|
setTimeout: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const throttler = new SimpleIdentifyThrottler(2);
|
let throttler: SimpleIdentifyThrottler;
|
||||||
|
const controller = new AbortController();
|
||||||
|
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
|
||||||
const NOW = vi.fn().mockReturnValue(Date.now());
|
const TIME = Date.now();
|
||||||
|
const NOW = vi.fn().mockReturnValue(TIME);
|
||||||
global.Date.now = NOW;
|
global.Date.now = NOW;
|
||||||
|
|
||||||
|
const sleep = vi.spyOn(timers, 'setTimeout');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
throttler = new SimpleIdentifyThrottler(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sleep.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
test('basic case', async () => {
|
test('basic case', async () => {
|
||||||
// Those shouldn't wait since they're in different keys
|
// Those shouldn't wait since they're in different keys
|
||||||
|
await throttler.waitForIdentify(0, controller.signal);
|
||||||
await throttler.waitForIdentify(0);
|
|
||||||
expect(sleep).not.toHaveBeenCalled();
|
expect(sleep).not.toHaveBeenCalled();
|
||||||
|
|
||||||
await throttler.waitForIdentify(1);
|
await throttler.waitForIdentify(1, controller.signal);
|
||||||
expect(sleep).not.toHaveBeenCalled();
|
expect(sleep).not.toHaveBeenCalled();
|
||||||
|
|
||||||
// Those should wait
|
// Those should wait
|
||||||
|
await throttler.waitForIdentify(2, controller.signal);
|
||||||
await throttler.waitForIdentify(2);
|
|
||||||
expect(sleep).toHaveBeenCalledTimes(1);
|
expect(sleep).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
await throttler.waitForIdentify(3);
|
await throttler.waitForIdentify(3, controller.signal);
|
||||||
expect(sleep).toHaveBeenCalledTimes(2);
|
expect(sleep).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('does not call sleep with a negative time', async () => {
|
||||||
|
await throttler.waitForIdentify(0, controller.signal);
|
||||||
|
expect(sleep).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await throttler.waitForIdentify(0, controller.signal);
|
||||||
|
expect(sleep).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
// By overshooting, we're simulating a bug that existed prior to this test, where-in by enough time
|
||||||
|
// passing before the shard tried to identify for a subsequent time, the passed value would end up being negative
|
||||||
|
// (and this was unchecked). Node simply treats that as 1ms, so it wasn't particularly harmful, but they
|
||||||
|
// recently introduced a warning for it, so we want to avoid that.
|
||||||
|
NOW.mockReturnValueOnce(TIME + 10_000);
|
||||||
|
await throttler.waitForIdentify(0, controller.signal);
|
||||||
|
expect(sleep).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export class SimpleIdentifyThrottler implements IIdentifyThrottler {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const diff = state.resetsAt - Date.now();
|
const diff = state.resetsAt - Date.now();
|
||||||
if (diff <= 5_000) {
|
if (diff > 0 && diff <= 5_000) {
|
||||||
// To account for the latency the IDENTIFY payload goes through, we add a bit more wait time
|
// To account for the latency the IDENTIFY payload goes through, we add a bit more wait time
|
||||||
const time = diff + Math.random() * 1_500;
|
const time = diff + Math.random() * 1_500;
|
||||||
await sleep(time);
|
await sleep(time);
|
||||||
|
|||||||
Reference in New Issue
Block a user