linx-simulator2/node_modules/reconnect-core/index.js

134 lines
3.5 KiB
JavaScript

var EventEmitter = require('events').EventEmitter
var backoff = require('backoff')
module.exports =
function (createConnection) {
return function (opts, onConnect) {
onConnect = 'function' == typeof opts ? opts : onConnect
opts = 'object' == typeof opts ? opts : {initialDelay: 1e3, maxDelay: 30e3}
if(!onConnect)
onConnect = opts.onConnect
var emitter = new EventEmitter()
emitter.connected = false
emitter.reconnect = true
if(onConnect)
//use "connection" to match core (net) api.
emitter.on('connection', onConnect)
var backoffStrategy = opts.strategy || opts.type
var backoffMethod
if (typeof backoffStrategy == 'string')
backoffMethod = backoff[backoffStrategy](opts)
else
backoffMethod = backoffStrategy || backoff.fibonacci(opts)
if(opts.failAfter)
backoffMethod.failAfter(opts.failAfter);
backoffMethod.on('backoff', function (n, d, e) {
emitter.emit('backoff', n, d, e)
})
backoffMethod.on('fail', function (e) {
emitter.disconnect()
emitter.emit('fail', e)
})
var args
function attempt (n, delay) {
if(emitter.connected) return
if(!emitter.reconnect) return
emitter.emit('reconnect', n, delay)
var con = createConnection.apply(emitter, args)
emitter._connection = con
function onError (err) {
con.removeListener('error', onError)
emitter.emit('error', err)
onDisconnect(err)
}
function onDisconnect (err) {
emitter.connected = false
con.removeListener('close', onDisconnect)
con.removeListener('end' , onDisconnect)
//hack to make http not crash.
//HTTP IS THE WORST PROTOCOL.
if(con.constructor.name == 'Request')
con.on('error', function () {})
//emit disconnect before checking reconnect, so user has a chance to decide not to.
emitter.emit('disconnect', err)
if(!emitter.reconnect) return
try { backoffMethod.backoff() } catch (_) { }
}
con
.on('error', onError)
.on('close', onDisconnect)
.on('end' , onDisconnect)
if(opts.immediate || con.constructor.name == 'Request') {
emitter.connected = true
emitter.emit('connect', con)
emitter.emit('connection', con)
con.once('data', function () {
//this is the only way to know for sure that data is coming...
backoffMethod.reset()
})
} else {
con
.once('connect', function () {
backoffMethod.reset()
emitter.connected = true
if(onConnect)
con.removeListener('connect', onConnect)
emitter.emit('connect', con)
//also support net style 'connection' method.
emitter.emit('connection', con)
})
}
}
emitter.connect =
emitter.listen = function () {
this.reconnect = true
if(emitter.connected) return
backoffMethod.reset()
backoffMethod.on('ready', attempt)
if (!args) {
var len = arguments.length;
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
}
attempt(0, 0)
return emitter
}
//force reconnection
emitter.disconnect = function () {
this.reconnect = false
if(emitter._connection)
emitter._connection.end()
return emitter
}
emitter.reset = function () {
backoffMethod.reset()
attempt(0, 0)
}
return emitter
}
}