Merge pull request #1044 from ripple/connection-timeout

Add a 2-second timeout for connect()
This commit is contained in:
FKSRipple
2019-10-23 18:19:39 -07:00
committed by GitHub
2 changed files with 18 additions and 4 deletions

View File

@@ -8,7 +8,7 @@ import {RippledError, DisconnectedError, NotConnectedError,
RippledNotInitializedError} from './errors' RippledNotInitializedError} from './errors'
export interface ConnectionOptions { export interface ConnectionOptions {
trace?: boolean, trace?: boolean
proxy?: string proxy?: string
proxyAuthorization?: string proxyAuthorization?: string
authorization?: string authorization?: string
@@ -16,7 +16,8 @@ export interface ConnectionOptions {
key?: string key?: string
passphrase?: string passphrase?: string
certificate?: string certificate?: string
timeout?: number timeout?: number,
connectionTimeout?: number
} }
class Connection extends EventEmitter { class Connection extends EventEmitter {
@@ -43,6 +44,7 @@ class Connection extends EventEmitter {
private _onUnexpectedCloseBound: null|((...args: any[]) => void) = null private _onUnexpectedCloseBound: null|((...args: any[]) => void) = null
private _fee_base: null|number = null private _fee_base: null|number = null
private _fee_ref: null|number = null private _fee_ref: null|number = null
private _connectionTimeout: number
constructor(url, options: ConnectionOptions = {}) { constructor(url, options: ConnectionOptions = {}) {
super() super()
@@ -61,6 +63,7 @@ class Connection extends EventEmitter {
this._passphrase = options.passphrase this._passphrase = options.passphrase
this._certificate = options.certificate this._certificate = options.certificate
this._timeout = options.timeout || (20 * 1000) this._timeout = options.timeout || (20 * 1000)
this._connectionTimeout = options.connectionTimeout || 2000
} }
_updateLedgerVersions(data) { _updateLedgerVersions(data) {
@@ -283,7 +286,11 @@ class Connection extends EventEmitter {
connect(): Promise<void> { connect(): Promise<void> {
this._clearReconnectTimer() this._clearReconnectTimer()
return new Promise((resolve, reject) => { return new Promise<void>((resolve, reject) => {
const connectTimeout = setTimeout(() => {
reject(new ConnectionError(`Error: connect() timed out after ${this._connectionTimeout} ms. ` +
`If your internet connection is working, the rippled server may be blocked or inaccessible.`))
}, this._connectionTimeout)
if (!this._url) { if (!this._url) {
reject(new ConnectionError( reject(new ConnectionError(
'Cannot connect because no server was specified')) 'Cannot connect because no server was specified'))
@@ -311,7 +318,10 @@ class Connection extends EventEmitter {
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this, true, this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this, true,
resolve, reject) resolve, reject)
this._ws.once('close', this._onUnexpectedCloseBound) this._ws.once('close', this._onUnexpectedCloseBound)
this._ws.once('open', () => this._onOpen().then(resolve, reject)) this._ws.once('open', () => {
clearTimeout(connectTimeout);
return this._onOpen().then(resolve, reject)
})
} }
}) })
} }

View File

@@ -4772,4 +4772,8 @@ describe('RippleAPI - offline', function () {
assert.throws(() => new RippleAPI({ server: 'wss//s:1' })); assert.throws(() => new RippleAPI({ server: 'wss//s:1' }));
}); });
xit('RippleAPI connect() times out after 2 seconds', function () {
// TODO: Use a timer mock like https://jestjs.io/docs/en/timer-mocks
// to test that connect() times out after 2 seconds.
});
}); });