mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-23 02:31:26 +01:00
[PM-6426] Implementing methodology for having a fallback to setTimeout if the browser context is lost in some manner
This commit is contained in:
parent
9cf7e0590a
commit
e82a52961b
@ -80,23 +80,6 @@ describe("BrowserTaskSchedulerService", () => {
|
||||
});
|
||||
|
||||
describe("setTimeout", () => {
|
||||
it("uses the global setTimeout API if the delay is less than 1000ms", async () => {
|
||||
const delayInMs = 999;
|
||||
jest.spyOn(globalThis, "setTimeout");
|
||||
|
||||
await browserTaskSchedulerService.setTimeout(
|
||||
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||
delayInMs,
|
||||
);
|
||||
|
||||
expect(globalThis.setTimeout).toHaveBeenCalledWith(expect.any(Function), delayInMs);
|
||||
expect(chrome.alarms.create).not.toHaveBeenCalledWith(
|
||||
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||
{ delayInMinutes: 1 },
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
|
||||
it("creates a timeout alarm", async () => {
|
||||
await browserTaskSchedulerService.setTimeout(
|
||||
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||
@ -142,5 +125,22 @@ describe("BrowserTaskSchedulerService", () => {
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
|
||||
it("uses the global setTimeout API if the delay is less than 1000ms", async () => {
|
||||
const delayInMs = 15000;
|
||||
jest.spyOn(globalThis, "setTimeout");
|
||||
|
||||
await browserTaskSchedulerService.setTimeout(
|
||||
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||
delayInMs,
|
||||
);
|
||||
|
||||
expect(globalThis.setTimeout).toHaveBeenCalledWith(expect.any(Function), delayInMs);
|
||||
expect(chrome.alarms.create).toHaveBeenCalledWith(
|
||||
`${userUuid}__${ScheduledTaskNames.loginStrategySessionTimeout}`,
|
||||
{ delayInMinutes: 0.5 },
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -52,15 +52,22 @@ export class BrowserTaskSchedulerServiceImplementation
|
||||
taskName: ScheduledTaskName,
|
||||
delayInMs: number,
|
||||
): Promise<number | NodeJS.Timeout> {
|
||||
const delayInMinutes = delayInMs / 1000 / 60;
|
||||
if (delayInMinutes < 1) {
|
||||
return super.setTimeout(taskName, delayInMs);
|
||||
}
|
||||
|
||||
this.validateRegisteredTask(taskName);
|
||||
|
||||
const delayInMinutes = delayInMs / 1000 / 60;
|
||||
const alarmName = await this.getActiveUserAlarmName(taskName);
|
||||
await this.scheduleAlarm(alarmName, { delayInMinutes });
|
||||
await this.scheduleAlarm(alarmName, {
|
||||
delayInMinutes: this.getUpperBoundDelayInMinutes(delayInMinutes),
|
||||
});
|
||||
|
||||
// If the delay is less than a minute, we want to attempt to trigger the task through a setTimeout.
|
||||
// The alarm previously scheduled will be used as a backup in case the setTimeout fails.
|
||||
if (delayInMinutes < 1) {
|
||||
return globalThis.setTimeout(async () => {
|
||||
await this.triggerTask(alarmName);
|
||||
await this.clearScheduledAlarm(alarmName);
|
||||
}, delayInMs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -396,4 +403,16 @@ export class BrowserTaskSchedulerServiceImplementation
|
||||
private isNonChromeEnvironment(): boolean {
|
||||
return typeof browser !== "undefined" && !!browser.alarms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the upper bound delay in minutes for a given delay in minutes. This is
|
||||
* used to ensure that the delay is at least 1 minute in non-Chrome environments.
|
||||
* In Chrome environments, the delay can be as low as 0.5 minutes.
|
||||
*
|
||||
* @param delayInMinutes - The delay in minutes.
|
||||
*/
|
||||
private getUpperBoundDelayInMinutes(delayInMinutes: number): number {
|
||||
const minDelayInMinutes = this.isNonChromeEnvironment() ? 1 : 0.5;
|
||||
return Math.max(minDelayInMinutes, delayInMinutes);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user