Skip to content

Commit

Permalink
Replace setTimeout with alarms (#218)
Browse files Browse the repository at this point in the history
* Replace setTimeout with alarms

* Remove logs
  • Loading branch information
rafaelgomesxyz authored Dec 4, 2022
1 parent e448d14 commit 3818e39
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 46 deletions.
49 changes: 21 additions & 28 deletions src/common/AutoSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { getServiceApi, ServiceApi } from '@apis/ServiceApi';
import { TraktSync } from '@apis/TraktSync';
import { BrowserAction } from '@common/BrowserAction';
import { StorageValuesOptions } from '@common/BrowserStorage';
import { StorageOptionsChangeData } from '@common/Events';
import { I18N } from '@common/I18N';
import { RequestError } from '@common/RequestError';
import { Shared } from '@common/Shared';
Expand All @@ -12,37 +11,36 @@ import { getServices, Service } from '@models/Service';
import '@services-apis';
import { getSyncStore } from '@stores/SyncStore';
import { PartialDeep } from 'type-fest';
import browser, { Alarms as WebExtAlarms } from 'webextension-polyfill';

class _AutoSync {
isChecking = false;
checkTimeoutId: number | null = null;
async initFromBackground() {
const existingAlarm = await browser.alarms.get('check-auto-sync');
if (existingAlarm) {
return;
}

init() {
void this.check();
Shared.events.subscribe('STORAGE_OPTIONS_CHANGE', null, this.onStorageOptionsChange);
browser.alarms.create('check-auto-sync', {
delayInMinutes: 1,
// Check again every hour
periodInMinutes: 60,
});
}

onStorageOptionsChange = (data: StorageOptionsChangeData) => {
if (data.options?.services) {
const doCheck = Object.values(data.options.services).some(
(serviceValue) =>
serviceValue && ('autoSync' in serviceValue || 'autoSyncDays' in serviceValue)
);
if (doCheck) {
void this.check();
}
}
};
addBackgroundListeners() {
browser.alarms.onAlarm.addListener(this.onAlarm);
}

async check() {
if (this.isChecking) {
private onAlarm = (alarm: WebExtAlarms.Alarm) => {
if (alarm.name !== 'check-auto-sync') {
return;
}
this.isChecking = true;

if (this.checkTimeoutId !== null) {
window.clearTimeout(this.checkTimeoutId);
}
void this.check();
};

private async check() {
await Shared.waitForInit();

const now = Utils.unix();
const servicesToSync = getServices().filter((service) => {
Expand Down Expand Up @@ -70,11 +68,6 @@ class _AutoSync {
await BrowserAction.setTitle();
await BrowserAction.setStaticIcon();
}

// Check again every hour
this.checkTimeoutId = window.setTimeout(() => void this.check(), 3600000);

this.isChecking = false;
}

private async sync(services: Service[], now: number) {
Expand Down
39 changes: 23 additions & 16 deletions src/common/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Shared } from '@common/Shared';
import { Utils } from '@common/Utils';
import { ScrobbleItemValues } from '@models/Item';
import { TraktItemValues } from '@models/TraktItem';
import browser, { Alarms as WebExtAlarms } from 'webextension-polyfill';

export type CacheItems<T extends (keyof CacheValues)[]> = {
[K in T[number]]: CacheItem<K>;
Expand Down Expand Up @@ -89,28 +90,39 @@ class _Cache {
urlsToTraktItems: 24 * 60 * 60,
};

private isChecking = false;
private checkTimeout: number | null = null;

readonly storageKeys = Object.keys(this.ttl).map(
(key) => `${key}Cache`
) as (keyof CacheStorageValues)[];

timestamp = 0;

init() {
void this.check();
async initFromBackground() {
const existingAlarm = await browser.alarms.get('check-cache');
if (existingAlarm) {
return;
}

browser.alarms.create('check-cache', {
delayInMinutes: 1,
// Check again every hour
periodInMinutes: 60,
});
}

addBackgroundListeners() {
browser.alarms.onAlarm.addListener(this.onAlarm);
}

async check() {
if (this.isChecking) {
private onAlarm = (alarm: WebExtAlarms.Alarm) => {
if (alarm.name !== 'check-cache') {
return;
}
this.isChecking = true;

if (this.checkTimeout !== null) {
window.clearTimeout(this.checkTimeout);
}
void this.check();
};

private async check() {
await Shared.waitForInit();

const now = Utils.unix();
for (const [key, ttl] of Object.entries(this.ttl) as [keyof CacheValues, number][]) {
Expand All @@ -127,11 +139,6 @@ class _Cache {
}
await Shared.storage.set({ [storageKey]: cache }, false);
}

// Check again every hour
this.checkTimeout = window.setTimeout(() => void this.check(), 3600000);

this.isChecking = false;
}

async get<K extends keyof CacheValues>(key: K): Promise<CacheItem<K>>;
Expand Down
12 changes: 12 additions & 0 deletions src/common/Shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export interface SharedValues {
storage: typeof BrowserStorage;
errors: typeof Errors;
events: typeof EventDispatcher;

waitForInit: () => Promise<unknown>;
finishInit: () => void;
}

export type BrowserPrefix = 'moz' | 'chrome' | 'unknown';
Expand All @@ -38,6 +41,12 @@ const browserPrefix = browser
? (browser.runtime.getURL('/').split('-')[0] as BrowserPrefix)
: 'unknown';

let initPromiseResolve: (value: unknown) => void = () => {
// Do nothing
};

const initPromise = new Promise((resolve) => (initPromiseResolve = resolve));

export const Shared: SharedValues = {
DATABASE_URL: 'https://uts.rafaelgomes.xyz/api',

Expand All @@ -55,4 +64,7 @@ export const Shared: SharedValues = {
storage: {} as typeof BrowserStorage,
errors: {} as typeof Errors,
events: {} as typeof EventDispatcher,

waitForInit: () => initPromise,
finishInit: () => initPromiseResolve(null),
};
8 changes: 6 additions & 2 deletions src/modules/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import '@images/uts-icon-38.png';
import '@images/uts-icon-selected-19.png';
import '@images/uts-icon-selected-38.png';

Cache.addBackgroundListeners();
AutoSync.addBackgroundListeners();

const init = async () => {
Shared.pageType = 'background';
await BrowserStorage.init();
Expand All @@ -28,9 +31,10 @@ const init = async () => {
Notifications.init();
RequestsManager.init();
ScriptInjector.init();
Cache.init();
AutoSync.init();
await Cache.initFromBackground();
await AutoSync.initFromBackground();
Messaging.init();
Shared.finishInit();
};

Messaging.addHandlers({
Expand Down
1 change: 1 addition & 0 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ const getManifest = (browserName: string): string => {
default_title: 'Universal Trakt Scrobbler',
},
permissions: [
'alarms',
'identity',
'storage',
'unlimitedStorage',
Expand Down

0 comments on commit 3818e39

Please sign in to comment.