summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-11-16 12:07:19 +0100
committerAndrej Mihajlov <and@mullvad.net>2018-11-16 14:42:38 +0100
commit9bf25d620ea887f549a937ae6281f75386dedce4 (patch)
treefc8c222b1b5217a6887f26d7fafa5054b0b63ba3 /gui
parentd12bc4254b7cab7251f237ad48686d456b8a89f0 (diff)
downloadmullvadvpn-9bf25d620ea887f549a937ae6281f75386dedce4.tar.xz
mullvadvpn-9bf25d620ea887f549a937ae6281f75386dedce4.zip
Move relay updates to the main process
Diffstat (limited to 'gui')
-rw-r--r--gui/packages/desktop/src/main/index.js80
-rw-r--r--gui/packages/desktop/src/renderer/app.js59
2 files changed, 79 insertions, 60 deletions
diff --git a/gui/packages/desktop/src/main/index.js b/gui/packages/desktop/src/main/index.js
index 7b12298a3e..6de9df40a5 100644
--- a/gui/packages/desktop/src/main/index.js
+++ b/gui/packages/desktop/src/main/index.js
@@ -20,11 +20,13 @@ import {
defaultSettings,
defaultTunnelStateTransition,
} from './daemon-rpc';
-import type { TunnelState, TunnelStateTransition, Settings } from './daemon-rpc';
+import type { RelayList, TunnelState, TunnelStateTransition, Settings } from './daemon-rpc';
import ReconnectionBackoff from './reconnection-backoff';
import { resolveBin } from './proc';
+const RELAY_LIST_UPDATE_INTERVAL = 60 * 60 * 1000;
+
const DAEMON_RPC_PATH =
process.platform === 'win32' ? '//./pipe/Mullvad VPN' : '/var/run/mullvad-vpn';
@@ -44,6 +46,8 @@ const ApplicationMain = {
_tunnelState: defaultTunnelStateTransition(),
_settings: defaultSettings(),
+ _relays: ({ countries: [] }: RelayList),
+ _relaysInterval: (null: ?IntervalID),
run() {
// Since electron's GPU blacklists are broken, GPU acceleration won't work on older distros
@@ -275,6 +279,18 @@ const ApplicationMain = {
return this._recoverFromBootstrapError(error);
}
+ // fetch relays
+ try {
+ this._setRelays(await this._daemonRpc.getRelayLocations());
+ } catch (error) {
+ log.error(`Failed to fetch relay locations: ${error.message}`);
+
+ return this._recoverFromBootstrapError(error);
+ }
+
+ // start periodic updates
+ this._startRelaysPeriodicUpdates();
+
// reset the reconnect backoff when connection established.
this._reconnectBackoff.reset();
@@ -285,19 +301,33 @@ const ApplicationMain = {
},
_onDaemonDisconnected(error: ?Error) {
+ // make sure we were connected before to distinguish between a failed attempt to reconnect and
+ // connection loss.
+ const wasConnected = this._connectedToDaemon;
+
+ if (wasConnected) {
+ this._connectedToDaemon = false;
+
+ // stop periodic updates
+ this._stopRelaysPeriodicUpdates();
+
+ // notify renderer process
+ if (this._windowController) {
+ this._windowController.send('daemon-disconnected', error ? error.message : null);
+ }
+ }
+
// recover connection on error
if (error) {
- log.debug(`Lost connection to daemon: ${error.message}`);
+ if (wasConnected) {
+ log.error(`Lost connection to daemon: ${error.message}`);
+ } else {
+ log.error(`Failed to connect to daemon: ${error.message}`);
+ }
this._reconnectToDaemon();
} else {
- log.info(`Disconnected from the daemon`);
- }
-
- this._connectedToDaemon = false;
-
- if (this._windowController) {
- this._windowController.send('daemon-disconnected', error ? error.message : null);
+ log.info('Disconnected from the daemon');
}
},
@@ -361,6 +391,37 @@ const ApplicationMain = {
}
},
+ _setRelays(newRelayList: RelayList) {
+ this._relays = newRelayList;
+
+ if (this._windowController) {
+ this._windowController.send('relays-changed', newRelayList);
+ }
+ },
+
+ _startRelaysPeriodicUpdates() {
+ log.debug('Start relays periodic updates');
+
+ const handler = async () => {
+ try {
+ this._setRelays(await this._daemonRpc.getRelayLocations());
+ } catch (error) {
+ log.error(`Failed to fetch relay locations: ${error.message}`);
+ }
+ };
+
+ this._relaysInterval = setInterval(handler, RELAY_LIST_UPDATE_INTERVAL);
+ },
+
+ _stopRelaysPeriodicUpdates() {
+ if (this._relaysInterval) {
+ clearInterval(this._relaysInterval);
+ this._relaysInterval = null;
+
+ log.debug('Stop relays periodic updates');
+ }
+ },
+
_updateTrayIcon(tunnelState: TunnelState) {
const iconTypes: { [TunnelState]: TrayIconType } = {
connected: 'secured',
@@ -408,6 +469,7 @@ const ApplicationMain = {
this._connectedToDaemon,
this._tunnelState,
this._settings,
+ this._relays,
);
});
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index e21a64aafb..fd863ccb50 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -42,8 +42,6 @@ import DaemonRpcProxy, {
import type { ReduxStore } from './redux/store';
-const RELAY_LIST_UPDATE_INTERVAL = 60 * 60 * 1000;
-
export default class AppRenderer {
_notificationController = new NotificationController();
_memoryHistory = createMemoryHistory();
@@ -59,14 +57,6 @@ export default class AppRenderer {
this._reduxActions.account.updateAccountExpiry(expiry);
},
);
- _relayListCache = new RelayListCache(
- () => {
- return this._daemonRpc.getRelayLocations();
- },
- (relayList) => {
- this._updateRelayLocations(relayList);
- },
- );
_tunnelState = defaultTunnelStateTransition();
_settings = defaultSettings();
@@ -123,6 +113,10 @@ export default class AppRenderer {
this._setSettings(newSettings);
});
+ ipcRenderer.on('relays-changed', (_event: Event, newRelays: RelayList) => {
+ this._setRelays(newRelays);
+ });
+
// Request the initial state from main process
ipcRenderer.on(
'get-state-reply',
@@ -131,9 +125,11 @@ export default class AppRenderer {
isConnected: boolean,
tunnelState: TunnelStateTransition,
settings: Settings,
+ relays: RelayList,
) => {
this._setTunnelState(tunnelState);
this._setSettings(settings);
+ this._setRelays(relays);
if (isConnected) {
this._onDaemonConnected();
@@ -314,11 +310,7 @@ export default class AppRenderer {
actions.account.updateAccountHistory(accountHistory);
}
- _updateRelayLocations(relayList: RelayList) {
- const actions = this._reduxActions;
-
- log.info('Got relay locations');
-
+ _setRelays(relayList: RelayList) {
const locations = relayList.countries.map((country) => ({
name: country.name,
code: country.code,
@@ -333,7 +325,7 @@ export default class AppRenderer {
})),
}));
- actions.settings.updateRelayLocations(locations);
+ this._reduxActions.settings.updateRelayLocations(locations);
}
async _fetchLocation() {
@@ -445,8 +437,6 @@ export default class AppRenderer {
log.error(`Cannot fetch the current version: ${error.message}`);
}
- this._relayListCache.startUpdating();
-
try {
await this._fetchAccountHistory();
} catch (error) {
@@ -466,8 +456,6 @@ export default class AppRenderer {
_onDaemonDisconnected(error: ?Error) {
const actions = this._reduxActions;
- this._relayListCache.stopUpdating();
-
// recover connection on error
if (error) {
// only send to the connecting to daemon view if the daemon was
@@ -706,34 +694,3 @@ export class AccountDataCache {
this._watchers.splice(0).forEach(notify);
}
}
-
-class RelayListCache {
- _fetch: () => Promise<RelayList>;
- _listener: (RelayList) => void;
- _updateTimer: ?IntervalID = null;
-
- constructor(fetch: () => Promise<RelayList>, listener: (RelayList) => void) {
- this._fetch = fetch;
- this._listener = listener;
- }
-
- startUpdating() {
- this.stopUpdating();
- this._updateTimer = setInterval(() => this._update(), RELAY_LIST_UPDATE_INTERVAL);
- this._update();
- }
-
- stopUpdating() {
- if (this._updateTimer) {
- clearInterval(this._updateTimer);
- }
- }
-
- async _update() {
- try {
- this._listener(await this._fetch());
- } catch (error) {
- log.error(`Cannot fetch the relay locations: ${error.message}`);
- }
- }
-}