diff options
| author | Erik Larkö <erik@mullvad.net> | 2017-08-29 12:13:25 +0200 |
|---|---|---|
| committer | Erik Larkö <erik@mullvad.net> | 2017-08-29 12:13:25 +0200 |
| commit | 6fd2fed683adcaac99e1b0b6d46ff80ba766b746 (patch) | |
| tree | 8b6ccb51394741d1f3371d239cc79435c8dfe84e | |
| parent | a257fe44b7ccf8d4712cbfc08134a1a658d8ebaa (diff) | |
| parent | 18f76dcc47bf91b9b2524da79117288b972ec65a (diff) | |
| download | mullvadvpn-6fd2fed683adcaac99e1b0b6d46ff80ba766b746.tar.xz mullvadvpn-6fd2fed683adcaac99e1b0b6d46ff80ba766b746.zip | |
Merge branch 'ipc-timeout'
| -rw-r--r-- | app/lib/ipc-facade.js | 5 | ||||
| -rw-r--r-- | app/lib/jsonrpc-ws-ipc.js | 29 | ||||
| -rw-r--r-- | test/ipc.spec.js | 7 |
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'); |
