mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-06 09:20:43 +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", () => {
|
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 () => {
|
it("creates a timeout alarm", async () => {
|
||||||
await browserTaskSchedulerService.setTimeout(
|
await browserTaskSchedulerService.setTimeout(
|
||||||
ScheduledTaskNames.loginStrategySessionTimeout,
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
@ -142,5 +125,22 @@ describe("BrowserTaskSchedulerService", () => {
|
|||||||
expect.any(Function),
|
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,
|
taskName: ScheduledTaskName,
|
||||||
delayInMs: number,
|
delayInMs: number,
|
||||||
): Promise<number | NodeJS.Timeout> {
|
): Promise<number | NodeJS.Timeout> {
|
||||||
const delayInMinutes = delayInMs / 1000 / 60;
|
|
||||||
if (delayInMinutes < 1) {
|
|
||||||
return super.setTimeout(taskName, delayInMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.validateRegisteredTask(taskName);
|
this.validateRegisteredTask(taskName);
|
||||||
|
|
||||||
|
const delayInMinutes = delayInMs / 1000 / 60;
|
||||||
const alarmName = await this.getActiveUserAlarmName(taskName);
|
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 {
|
private isNonChromeEnvironment(): boolean {
|
||||||
return typeof browser !== "undefined" && !!browser.alarms;
|
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