bot18
Version:
A high-frequency cryptocurrency trading bot by Zenbot creator @carlos8f
116 lines (92 loc) • 3.01 kB
JavaScript
var EventEmitter = require('events').EventEmitter
var backoff = require('backoff')
var noop = function () {}
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 = opts.emitter || new EventEmitter()
emitter.connected = false
emitter.reconnect = true
if(onConnect)
emitter.on('connect', onConnect)
var backoffMethod = (backoff[opts.type] || backoff.fibonacci) (opts)
backoffMethod.on('backoff', function (n, d) {
emitter.emit('backoff', n, d)
})
var args
var cleanup = noop
backoffMethod.on('ready', attempt)
function attempt (n, delay) {
if(!emitter.reconnect) return
cleanup()
emitter.emit('reconnect', n, delay)
var con = createConnection.apply(null, args)
if (con !== emitter._connection)
emitter.emit('connection', con)
emitter._connection = con
cleanup = onCleanup
function onCleanup(err) {
cleanup = noop
con.removeListener('connect', connect)
con.removeListener('error', onDisconnect)
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', noop)
}
function onDisconnect (err) {
emitter.connected = false
onCleanup(err)
//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 (_) { }
}
function connect() {
backoffMethod.reset()
emitter.connected = true
if(onConnect)
con.removeListener('connect', onConnect)
emitter.emit('connect', con)
}
con
.on('error', onDisconnect)
.on('close', onDisconnect)
.on('end' , onDisconnect)
if(opts.immediate || con.constructor.name == 'Request') {
emitter.connected = true
emitter.emit('connect', con)
con.once('data', function () {
//this is the only way to know for sure that data is coming...
backoffMethod.reset()
})
} else {
con.on('connect', connect)
}
}
emitter.connect =
emitter.listen = function () {
this.reconnect = true
backoffMethod.reset()
args = [].slice.call(arguments)
attempt(0, 0)
return emitter
}
//force reconnection
emitter.end =
emitter.disconnect = function () {
emitter.reconnect = false
if(emitter._connection)
emitter._connection.end()
emitter.emit('disconnect')
return emitter
}
return emitter
}
}