diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2018-08-07 15:36:47 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2018-08-08 16:25:34 +0200 |
| commit | 9237ae84242b2dd1b29b345e8569ce3f8169ead9 (patch) | |
| tree | c656fb91211e52a5706fe5ee04c8b7c8d3205371 /app | |
| parent | 3e63b2509962201cd25861dc752b2a404f1b614d (diff) | |
| download | mullvadvpn-9237ae84242b2dd1b29b345e8569ce3f8169ead9.tar.xz mullvadvpn-9237ae84242b2dd1b29b345e8569ce3f8169ead9.zip | |
Add AccountDataState to filter out number of requests to get_account_data
Diffstat (limited to 'app')
| -rw-r--r-- | app/app.js | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/app/app.js b/app/app.js index 4ccf992b03..369c51be2d 100644 --- a/app/app.js +++ b/app/app.js @@ -28,6 +28,7 @@ import daemonActions from './redux/daemon/actions'; import type { RpcCredentials } from './lib/rpc-address-file'; import type { DaemonRpcProtocol, + AccountData, ConnectionObserver as DaemonConnectionObserver, } from './lib/daemon-rpc'; import type { ReduxStore } from './redux/store'; @@ -45,6 +46,7 @@ export default class AppRenderer { _memoryHistory = createMemoryHistory(); _reduxStore: ReduxStore; _reduxActions: *; + _accountDataState = new AccountDataState(); constructor() { const store = configureStore(null, this._memoryHistory); @@ -196,6 +198,9 @@ export default class AppRenderer { ]); actions.account.loggedOut(); actions.history.replace('/login'); + + // reset account data state on log out + this._accountDataState = new AccountDataState(); } catch (e) { log.info('Failed to logout: ', e.message); } @@ -278,13 +283,29 @@ export default class AppRenderer { async updateAccountExpiry() { const actions = this._reduxActions; + const accountDataState = this._accountDataState; + + // Bail if something else requested an update to account data + // or if account data cache was updated recently. + if (accountDataState.isUpdating() || !accountDataState.needsUpdate()) { + return; + } + try { const accountToken = await this._daemonRpc.getAccount(); if (!accountToken) { throw new NoAccountError(); } - const accountData = await this._daemonRpc.getAccountData(accountToken); - actions.account.updateAccountExpiry(accountData.expiry); + + const accountData = await accountDataState.update(() => { + return this._daemonRpc.getAccountData(accountToken); + }); + + // Check if account token is still the same after receiving account data + const currentAccountToken = this._reduxStore.getState().account.accountToken; + if (currentAccountToken === accountToken) { + actions.account.updateAccountExpiry(accountData.expiry); + } } catch (e) { log.error(`Failed to update account expiry: ${e.message}`); } @@ -579,3 +600,32 @@ export default class AppRenderer { } } } + +// Helper class to keep track of account data updates +class AccountDataState { + _expiresAt: ?Date; + _isUpdating = false; + + isUpdating() { + return this._isUpdating; + } + + needsUpdate() { + return !this._expiresAt || this._expiresAt < new Date(); + } + + async update(fn: () => Promise<AccountData>): Promise<AccountData> { + this._isUpdating = true; + + try { + const accountData = await fn(); + this._expiresAt = new Date(Date.now() + 60 * 1000); // 60s expiration + + return accountData; + } catch (error) { + throw error; + } finally { + this._isUpdating = false; + } + } +} |
