Skip to content

Commit 913887d

Browse files
fix: Handle scheduled events close to current time gracefully (#3510)
When an event is supposed to be scheduled immediately there is a chance that by the time we get to schedule it the time left is less than 0 milliseconds. In that case we should just execute immediately. This is most likely to happen during initialization. --------- Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
1 parent b814848 commit 913887d

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

packages/snaps-controllers/src/cronjob/CronjobController.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,54 @@ describe('CronjobController', () => {
443443
cronjobController.destroy();
444444
});
445445

446+
it('handles scheduled event close to current time gracefully', () => {
447+
const rootMessenger = getRootCronjobControllerMessenger();
448+
const controllerMessenger =
449+
getRestrictedCronjobControllerMessenger(rootMessenger);
450+
451+
const cronjobController = new CronjobController({
452+
messenger: controllerMessenger,
453+
state: {
454+
events: {
455+
foo: {
456+
id: 'foo',
457+
recurring: false,
458+
date: '2022-01-01T00:00:01.000Z',
459+
schedule: '2022-01-01T00:00:01.000Z',
460+
scheduledAt: new Date().toISOString(),
461+
snapId: MOCK_SNAP_ID,
462+
request: {
463+
method: 'handleEvent',
464+
params: ['p1'],
465+
},
466+
},
467+
},
468+
},
469+
});
470+
471+
rootMessenger.subscribe('CronjobController:stateChange', () => {
472+
jest.advanceTimersByTime(inMilliseconds(2, Duration.Second));
473+
});
474+
475+
cronjobController.init();
476+
477+
expect(rootMessenger.call).toHaveBeenNthCalledWith(
478+
1,
479+
'SnapController:handleRequest',
480+
{
481+
snapId: MOCK_SNAP_ID,
482+
origin: METAMASK_ORIGIN,
483+
handler: HandlerType.OnCronjob,
484+
request: {
485+
method: 'handleEvent',
486+
params: ['p1'],
487+
},
488+
},
489+
);
490+
491+
cronjobController.destroy();
492+
});
493+
446494
it('handles the `snapInstalled` event', () => {
447495
const rootMessenger = getRootCronjobControllerMessenger();
448496
const controllerMessenger =

packages/snaps-controllers/src/cronjob/CronjobController.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,13 @@ export class CronjobController extends BaseController<
415415
return;
416416
}
417417

418+
// When an event is supposed to be scheduled close to the current time
419+
// we may end up needing to execute immediately instead.
420+
if (ms <= 0) {
421+
this.#execute(event);
422+
return;
423+
}
424+
418425
const timer = new Timer(ms);
419426
timer.start(() => {
420427
this.#execute(event);

0 commit comments

Comments
 (0)