summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorErik Larkö <erik@mullvad.net>2017-08-29 12:13:25 +0200
committerErik Larkö <erik@mullvad.net>2017-08-29 12:13:25 +0200
commit6fd2fed683adcaac99e1b0b6d46ff80ba766b746 (patch)
tree8b6ccb51394741d1f3371d239cc79435c8dfe84e
parenta257fe44b7ccf8d4712cbfc08134a1a658d8ebaa (diff)
parent18f76dcc47bf91b9b2524da79117288b972ec65a (diff)
downloadmullvadvpn-6fd2fed683adcaac99e1b0b6d46ff80ba766b746.tar.xz
mullvadvpn-6fd2fed683adcaac99e1b0b6d46ff80ba766b746.zip
Merge branch 'ipc-timeout'
-rw-r--r--app/lib/ipc-facade.js5
-rw-r--r--app/lib/jsonrpc-ws-ipc.js29
-rw-r--r--test/ipc.spec.js7
3 files changed, 26 insertions, 15 deletions
diff --git a/app/lib/ipc-facade.js b/app/lib/ipc-facade.js
index 798b4d2805..3a0a4cc101 100644
--- a/app/lib/ipc-facade.js
+++ b/app/lib/ipc-facade.js
@@ -53,7 +53,10 @@ export class RealIpc implements IpcFacade {
}
getAccountData(accountNumber: AccountNumber): Promise<AccountData> {
- return this._ipc.send('get_account_data', accountNumber)
+ // send the IPC with 30s timeout since the backend will wait
+ // for a HTTP request before replying
+
+ return this._ipc.send('get_account_data', accountNumber, 30000)
.then(raw => {
if (typeof raw === 'object' && raw && raw.expiry) {
return raw;
diff --git a/app/lib/jsonrpc-ws-ipc.js b/app/lib/jsonrpc-ws-ipc.js
index 597d6830fe..46ccf51668 100644
--- a/app/lib/jsonrpc-ws-ipc.js
+++ b/app/lib/jsonrpc-ws-ipc.js
@@ -64,7 +64,7 @@ export class InvalidReply extends Error {
}
}
-const DEFAULT_TIMEOUT_MILLIS = 750;
+const DEFAULT_TIMEOUT_MILLIS = 5000;
export default class Ipc {
@@ -75,7 +75,6 @@ export default class Ipc {
_websocket: WebSocket;
_backoff: ReconnectionBackoff;
_websocketFactory: (string) => WebSocket;
- _sendTimeoutMillis: number;
constructor(connectionString: string, websocketFactory: ?(string)=>WebSocket) {
this._connectionString = connectionString;
@@ -83,7 +82,6 @@ export default class Ipc {
this._unansweredRequests = {};
this._subscriptions = {};
this._websocketFactory = websocketFactory || (connectionString => new WebSocket(connectionString));
- this._sendTimeoutMillis = DEFAULT_TIMEOUT_MILLIS;
this._backoff = new ReconnectionBackoff();
this._reconnect();
@@ -93,10 +91,6 @@ export default class Ipc {
this._connectionString = str;
}
- setSendTimeout(millis: number) {
- this._sendTimeoutMillis = millis;
- }
-
on(event: string, listener: (mixed) => void): Promise<*> {
log.info('Adding a listener to', event);
@@ -113,12 +107,13 @@ export default class Ipc {
});
}
- send(action: string, ...data: Array<mixed>): Promise<mixed> {
+ send(action: string, data: mixed, timeout: number = DEFAULT_TIMEOUT_MILLIS): Promise<mixed> {
return new Promise((resolve, reject) => {
const id = uuid.v4();
- const timerId = setTimeout(() => this._onTimeout(id), this._sendTimeoutMillis);
- const jsonrpcMessage = jsonrpc.request(id, action, data);
+ const params = this._prepareParams(data);
+ const timerId = setTimeout(() => this._onTimeout(id), timeout);
+ const jsonrpcMessage = jsonrpc.request(id, action, params);
this._unansweredRequests[id] = {
resolve: resolve,
reject: reject,
@@ -138,6 +133,20 @@ export default class Ipc {
});
}
+ _prepareParams(data: mixed): Array<mixed>|Object {
+ // JSONRPC only accepts arrays and objects as params, but
+ // this isn't very nice to use, so this method wraps other
+ // types in an array. The choice of array is based on try-and-error
+
+ if(data === undefined || data === null) {
+ return [];
+ } else if (Array.isArray(data) || typeof(data) === 'object') {
+ return data;
+ } else {
+ return [data];
+ }
+ }
+
_getWebSocket() {
return new Promise(resolve => {
if (this._websocket && this._websocket.readyState === 1) { // Connected
diff --git a/test/ipc.spec.js b/test/ipc.spec.js
index ae9c5ab815..6e02ab94b1 100644
--- a/test/ipc.spec.js
+++ b/test/ipc.spec.js
@@ -46,14 +46,14 @@ describe('The IPC server', () => {
ws.on('a message', (msg) => ws.replyOk(msg.id, 'a reply'));
- const decoy = ipc.send('a decoy')
+ const decoy = ipc.send('a decoy', [], 1)
.then(() => assert(false, 'Should not be called'))
.catch(e => {
if (e.name !== 'TimeOutError') {
throw e;
}
});
- const message = ipc.send('a message')
+ const message = ipc.send('a message', [], 1)
.then((reply) => expect(reply).to.equal('a reply'));
return Promise.all([message, decoy]);
@@ -62,8 +62,7 @@ describe('The IPC server', () => {
it('should timeout if no response is returned', () => {
const { ipc } = setupIpc();
- ipc.setSendTimeout(1);
- return ipc.send('a message')
+ return ipc.send('a message', [], 1)
.catch((e) => {
expect(e.name).to.equal('TimeOutError');
expect(e.message).to.contain('timed out');