diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-07-08 13:24:04 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-07-08 13:24:04 +0200 |
| commit | a77a58850d4e005df88acbac27782c0a382ce6b8 (patch) | |
| tree | 8c41f5052ea265b5470629be4612476e292e28d9 /gui/src/main | |
| parent | 91a30f07505eaea3f4669ba874ee497af43d89a3 (diff) | |
| parent | 3eaff61fca0121bb1a555624d00a6984d3e562c9 (diff) | |
| download | mullvadvpn-a77a58850d4e005df88acbac27782c0a382ce6b8.tar.xz mullvadvpn-a77a58850d4e005df88acbac27782c0a382ce6b8.zip | |
Merge branch 'improve-account-data-fetching'
Diffstat (limited to 'gui/src/main')
| -rw-r--r-- | gui/src/main/account-data-cache.ts | 35 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 15 |
2 files changed, 33 insertions, 17 deletions
diff --git a/gui/src/main/account-data-cache.ts b/gui/src/main/account-data-cache.ts index 8b81a29472..a79a934537 100644 --- a/gui/src/main/account-data-cache.ts +++ b/gui/src/main/account-data-cache.ts @@ -6,18 +6,21 @@ import consumePromise from '../shared/promise'; import { Scheduler } from '../shared/scheduler'; import { InvalidAccountError } from './errors'; -const EXPIRED_ACCOUNT_REFRESH_PERIOD = 60_000; - interface IAccountFetchWatcher { onFinish: () => void; onError: (error: Error) => void; } +// Account data is valid for 1 minute unless the account has expired. +const ACCOUNT_DATA_VALIDITY_SECONDS = 60_000; +// Account data is valid for 10 seconds if the account has expired. +const ACCOUNT_DATA_EXPIRED_VALIDITY_SECONDS = 10_000; + // An account data cache that helps to throttle RPC requests to get_account_data and retain the // cached value for 1 minute. export default class AccountDataCache { private currentAccount?: AccountToken; - private expiresAt?: Date; + private validUntil?: Date; private performingFetch = false; private waitStrategy = new WaitStrategy(); private fetchRetryScheduler = new Scheduler(); @@ -36,7 +39,7 @@ export default class AccountDataCache { } // Only fetch if value has expired - if (this.isExpired()) { + if (!this.isValid()) { if (watcher) { this.watchers.push(watcher); } @@ -59,7 +62,7 @@ export default class AccountDataCache { this.waitStrategy.reset(); this.performingFetch = false; - this.expiresAt = undefined; + this.validUntil = undefined; this.updateHandler(); this.notifyWatchers((watcher) => { watcher.onError(new Error('Cancelled')); @@ -72,14 +75,22 @@ export default class AccountDataCache { } } - private setValue(value: IAccountData) { - this.expiresAt = new Date(Date.now() + 60 * 1000); // 60s expiration - this.updateHandler(value); + private setValue(accountData: IAccountData) { + this.validUntil = this.getValidUntil(accountData); + this.updateHandler(accountData); this.notifyWatchers((watcher) => watcher.onFinish()); } - private isExpired() { - return !this.expiresAt || this.expiresAt < new Date(); + private isValid() { + return this.validUntil && this.validUntil > new Date(); + } + + private getValidUntil(accountData: IAccountData): Date { + if (hasExpired(accountData.expiry)) { + return new Date(Date.now() + ACCOUNT_DATA_EXPIRED_VALIDITY_SECONDS); + } else { + return new Date(Date.now() + ACCOUNT_DATA_VALIDITY_SECONDS); + } } private async performFetch(accountToken: AccountToken) { @@ -113,9 +124,7 @@ export default class AccountDataCache { const currentDate = new Date(); const oneMinuteBeforeExpiry = dateByAddingComponent(accountExpiry, DateComponent.minute, -1); - if (hasExpired(accountExpiry)) { - return EXPIRED_ACCOUNT_REFRESH_PERIOD; - } else if (oneMinuteBeforeExpiry >= currentDate && closeToExpiry(accountExpiry)) { + if (oneMinuteBeforeExpiry >= currentDate && closeToExpiry(accountExpiry)) { return oneMinuteBeforeExpiry.getTime() - currentDate.getTime(); } else { return undefined; diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index a139434020..8b047cb6c3 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -15,7 +15,7 @@ import * as path from 'path'; import { sprintf } from 'sprintf-js'; import * as uuid from 'uuid'; import config from '../config.json'; -import { hasExpired } from '../shared/account-expiry'; +import { closeToExpiry, hasExpired } from '../shared/account-expiry'; import { IApplication } from '../shared/application-types'; import BridgeSettingsBuilder from '../shared/bridge-settings-builder'; import { @@ -1049,14 +1049,20 @@ class ApplicationMain { } private registerWindowListener(windowController: WindowController) { - windowController.window?.on('show', () => { + windowController.window?.on('focus', () => { // cancel notifications when window appears this.notificationController.cancelPendingNotifications(); - this.updateAccountData(); + if ( + !this.accountData || + closeToExpiry(this.accountData.expiry, 4) || + hasExpired(this.accountData.expiry) + ) { + this.updateAccountData(); + } }); - windowController.window?.on('hide', () => { + windowController.window?.on('blur', () => { // ensure notification guard is reset this.notificationController.resetTunnelStateAnnouncements(); }); @@ -1172,6 +1178,7 @@ class ApplicationMain { return response; }); + IpcMainEventChannel.account.handleUpdateData(() => this.updateAccountData()); IpcMainEventChannel.accountHistory.handleClear(async () => { await this.daemonRpc.clearAccountHistory(); |
