Rewrite `WallClockListener` as `onTimeTravel`

This commit is contained in:
Evan Hahn 2022-05-31 16:22:31 +00:00 committed by GitHub
parent 11cfb4f76f
commit 6668348197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 30 deletions

View File

@ -1,28 +0,0 @@
// Copyright 2017-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global Whisper */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
let lastTime;
const interval = 1000;
let events;
function checkTime() {
const currentTime = Date.now();
if (currentTime > lastTime + interval * 2) {
events.trigger('timetravel');
}
lastTime = currentTime;
}
Whisper.WallClockListener = {
init(_events) {
events = _events;
lastTime = Date.now();
setInterval(checkTime, interval);
},
};
})();

View File

@ -55,6 +55,7 @@ import { removeStorageKeyJobQueue } from './jobs/removeStorageKeyJobQueue';
import { ourProfileKeyService } from './services/ourProfileKey';
import { notificationService } from './services/notifications';
import { areWeASubscriberService } from './services/areWeASubscriber';
import { startTimeTravelDetector } from './util/startTimeTravelDetector';
import { shouldRespondWithProfileKey } from './util/shouldRespondWithProfileKey';
import { LatestQueue } from './util/LatestQueue';
import { parseIntOrThrow } from './util/parseIntOrThrow';
@ -1726,7 +1727,10 @@ export async function startApp(): Promise<void> {
window.setAutoHideMenuBar(hideMenuBar);
window.setMenuBarVisibility(!hideMenuBar);
window.Whisper.WallClockListener.init(window.Whisper.events);
startTimeTravelDetector(() => {
window.Whisper.events.trigger('timetravel');
});
window.Whisper.ExpiringMessagesListener.init(window.Whisper.events);
window.Whisper.TapToViewMessagesListener.init(window.Whisper.events);

View File

@ -0,0 +1,59 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as sinon from 'sinon';
import { startTimeTravelDetector } from '../../util/startTimeTravelDetector';
describe('startTimeTravelDetector', () => {
let sandbox: sinon.SinonSandbox;
beforeEach(() => {
sandbox = sinon.createSandbox({ useFakeTimers: true });
});
afterEach(() => {
sandbox.restore();
});
it('calls the callback when the time between checks is more than 2 seconds', async function test() {
const callback = sandbox.fake();
startTimeTravelDetector(callback);
// Normal clock behavior
await sandbox.clock.tickAsync(1234);
await sandbox.clock.tickAsync(5678);
sinon.assert.notCalled(callback);
// Time travel ≤2s
sandbox.clock.setSystemTime(Date.now() + 1000);
await sandbox.clock.tickAsync(1000);
sinon.assert.notCalled(callback);
sandbox.clock.setSystemTime(Date.now() + 1999);
await sandbox.clock.tickAsync(1);
sinon.assert.notCalled(callback);
// Time travel >2s
sandbox.clock.setSystemTime(Date.now() + 2001);
await sandbox.clock.nextAsync();
sinon.assert.calledOnce(callback);
sandbox.clock.setSystemTime(Date.now() + 9999);
await sandbox.clock.nextAsync();
sinon.assert.calledTwice(callback);
// Normal clock behavior
await sandbox.clock.tickAsync(9876);
sinon.assert.calledTwice(callback);
});
it('can detect time travel right after initialization', async () => {
const callback = sandbox.fake();
startTimeTravelDetector(callback);
sandbox.clock.setSystemTime(Date.now() + 2001);
await sandbox.clock.nextAsync();
sinon.assert.calledOnce(callback);
});
});

View File

@ -0,0 +1,18 @@
// Copyright 2017-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
const INTERVAL = 1000;
export function startTimeTravelDetector(callback: () => unknown): void {
let lastTime = Date.now();
setInterval(() => {
const currentTime = Date.now();
const sinceLastTime = currentTime - lastTime;
if (sinceLastTime > INTERVAL * 2) {
callback();
}
lastTime = currentTime;
}, INTERVAL);
}

1
ts/window.d.ts vendored
View File

@ -550,7 +550,6 @@ export type WhisperType = {
MessageCollection: typeof MessageModelCollectionType;
GroupMemberConversation: WhatIsThis;
WallClockListener: WhatIsThis;
deliveryReceiptQueue: PQueue;
deliveryReceiptBatcher: BatcherType<Receipt>;