2022-06-14 17:10:53 +02:00
|
|
|
import { sequentialize } from "@bitwarden/common/misc/sequentialize";
|
|
|
|
import { throttle } from "@bitwarden/common/misc/throttle";
|
2019-02-02 16:17:44 +01:00
|
|
|
|
|
|
|
describe("throttle decorator", () => {
|
|
|
|
it("should call the function once at a time", async () => {
|
|
|
|
const foo = new Foo();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
promises.push(foo.bar(1));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
expect(foo.calls).toBe(10);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should call the function once at a time for each object", async () => {
|
|
|
|
const foo = new Foo();
|
|
|
|
const foo2 = new Foo();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
promises.push(foo.bar(1));
|
|
|
|
promises.push(foo2.bar(1));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
expect(foo.calls).toBe(10);
|
|
|
|
expect(foo2.calls).toBe(10);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should call the function limit at a time", async () => {
|
|
|
|
const foo = new Foo();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
promises.push(foo.baz(1));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
expect(foo.calls).toBe(10);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should call the function limit at a time for each object", async () => {
|
|
|
|
const foo = new Foo();
|
|
|
|
const foo2 = new Foo();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
promises.push(foo.baz(1));
|
|
|
|
promises.push(foo2.baz(1));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
expect(foo.calls).toBe(10);
|
|
|
|
expect(foo2.calls).toBe(10);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should work together with sequentialize", async () => {
|
|
|
|
const foo = new Foo();
|
|
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
promises.push(foo.qux(Math.floor(i / 2) * 2));
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
expect(foo.calls).toBe(5);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
class Foo {
|
|
|
|
calls = 0;
|
|
|
|
inflight = 0;
|
|
|
|
|
|
|
|
@throttle(1, () => "bar")
|
|
|
|
bar(a: number) {
|
|
|
|
this.calls++;
|
|
|
|
this.inflight++;
|
2021-02-04 16:49:23 +01:00
|
|
|
return new Promise((res) => {
|
2019-02-02 16:17:44 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
expect(this.inflight).toBe(1);
|
|
|
|
this.inflight--;
|
|
|
|
res(a * 2);
|
|
|
|
}, Math.random() * 10);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@throttle(5, () => "baz")
|
|
|
|
baz(a: number) {
|
|
|
|
this.calls++;
|
|
|
|
this.inflight++;
|
2021-02-04 16:49:23 +01:00
|
|
|
return new Promise((res) => {
|
2019-02-02 16:17:44 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
expect(this.inflight).toBeLessThanOrEqual(5);
|
|
|
|
this.inflight--;
|
|
|
|
res(a * 3);
|
|
|
|
}, Math.random() * 10);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-02-04 16:49:23 +01:00
|
|
|
@sequentialize((args) => "qux" + args[0])
|
2019-02-02 16:17:44 +01:00
|
|
|
@throttle(1, () => "qux")
|
|
|
|
qux(a: number) {
|
|
|
|
this.calls++;
|
|
|
|
this.inflight++;
|
2021-02-04 16:49:23 +01:00
|
|
|
return new Promise((res) => {
|
2019-02-02 16:17:44 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
expect(this.inflight).toBe(1);
|
|
|
|
this.inflight--;
|
|
|
|
res(a * 3);
|
|
|
|
}, Math.random() * 10);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|