UNPKG

abraxas

Version:

A streaming gearman client / worker / server (as you choose)

141 lines (113 loc) 5.11 kB
"use strict"; var net = require('net'); var util = require('util'); var through = require('through2'); var events = require('events'); var packet = require('gearman-packet'); var PacketHandler = require('./packet-handler'); var debugPacket = require('./debug-packet'); var AbraxasError = require('./errors'); var maxId = 0; var AbraxasSocket = module.exports = function (options) { if (!options) options = {}; if (!options.socket) { throw new Error("Invalid arguments in AbraxasSocket Gearman constructor, must include a socket"); } this.options = options; var packets = this.packets = new PacketHandler(); if (this.options.debug) { this.on('unknown-packet',function(packet){ console.error('Unknown packet',debugPacket(packet)) }); } if (!this.options.defaultEncoding) { this.options.defaultEncoding = null; } var self = this; this.connection = options.socket; this.connection.setMaxListeners(0); this.connected = true; this.connection.once('disconnect',function(){ self.disconnect() }); this.connection.setNoDelay(true); this.connection.setKeepAlive(true); this.refCount = 0; this.connection.unref(); if (this.connection.remoteAddress) { this.clientid = (++maxId)+'='+(net.isIPv4(this.connection.remoteAddress)?this.connection.remoteAddress:'['+this.connection.remoteAddress+']') + ':' + this.connection.remotePort; } else { var id = ++maxId; this.clientid = id+"=...connecting..."; this.connection.once('connect',function () { self.clientid = id+'='+(net.isIPv4(self.connection.localAddress)?self.connection.localAddress:'['+self.connection.localAddress+']') + ':' + self.connection.localPort; }); } var connectionError = function(error){ self.emitError(new AbraxasError.Connect(error)) } this.connection.once('error', connectionError); this.connection.once('connect', function () { self.connection.removeListener('error', connectionError); self.connection.once('error', function (error){ self.emitError(new AbraxasError.Socket(error)) }); }); this.connection.once('end', function(){ self.emit('disconnect') }); var input = this.connection; var output; var observe = function (stream,func) { if (!func) { func = stream; stream = null } var passthrough = function(data,enc,done){ func.apply(null,arguments); this.push(data,enc); done(); }; if (stream) { var thr = stream._readableState.objectMode ? through.obj : through; return stream.pipe(thr(passthrough)); } else { return through.obj(passthrough); } } if (this.options.trafficDump) input = observe(input,function(D){ self.emitRead(D) }); if (this.options.packetDump) output = observe(function(D){ self.emitWrite(D) }); input = input.pipe(new packet.Parser()); input.once('error', function(error){ self.emitError(new AbraxasError.Parser(error)) }); var emitter = new packet.Emitter(); this.socket = output ? output : emitter; if (output) output.pipe(emitter); output = emitter; output.once('error', function(error){ self.emitError(new AbraxasError.Emitter(error)) }); if (this.options.packetDump) input = observe(input,function(D){ self.emitRead(D) }); if (this.options.trafficDump) output = observe(output,function(D){ self.emitWrite(D) }); output.pipe(this.connection); var self = this; input.pipe(packets); packets.on('unknown', function (packet) { self.emitUnknownPacket(packet) }); events.EventEmitter.call(this); } util.inherits( AbraxasSocket, events.EventEmitter ); AbraxasSocket.prototype.disconnect = function () { if (!this.connected) return; if (this.socket) this.socket.end(); if (this.connection) this.connection.end(); this.connected = false; this.refCount = 0; if (this.connection) this.connection.unref() this.emit('disconnect',this); } AbraxasSocket.prototype.destroy = function () { if (this.connection instanceof net.Socket) this.connection.destroy(); this.disconnect(); } AbraxasSocket.prototype.emitError = function (error) { this.emit('error',error); } AbraxasSocket.prototype.emitUnknownPacket = function (packet) { if (events.EventEmitter.listenerCount(this,'unknown-packet')) return this.emit('unknown-packet',packet); } AbraxasSocket.prototype.emitRead = function (stuff) { if (events.EventEmitter.listenerCount(this,'read')) return this.emit('read',stuff); console.error(this.clientid,'READ',Buffer.isBuffer(stuff)?stuff:debugPacket(stuff)); } AbraxasSocket.prototype.emitWrite = function (stuff) { if (events.EventEmitter.listenerCount(this,'write')) return this.emit('write',stuff); console.error(this.clientid,'WRITE',Buffer.isBuffer(stuff)?stuff:debugPacket(stuff)); } AbraxasSocket.prototype.ref = function () { if (this.refCount++ == 0) { this.connection.ref() } } AbraxasSocket.prototype.unref = function () { if (--this.refCount == 0) { this.connection.unref() } }