You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.5 KiB
72 lines
1.5 KiB
'use strict'; |
|
|
|
var RingBuffer = require('./ring_buffer'); |
|
|
|
var Functor = function(session, method) { |
|
this._session = session; |
|
this._method = method; |
|
this._queue = new RingBuffer(Functor.QUEUE_SIZE); |
|
this._stopped = false; |
|
this.pending = 0; |
|
}; |
|
|
|
Functor.QUEUE_SIZE = 8; |
|
|
|
Functor.prototype.call = function(error, message, callback, context) { |
|
if (this._stopped) return; |
|
|
|
var record = { error: error, message: message, callback: callback, context: context, done: false }, |
|
called = false, |
|
self = this; |
|
|
|
this._queue.push(record); |
|
|
|
if (record.error) { |
|
record.done = true; |
|
this._stop(); |
|
return this._flushQueue(); |
|
} |
|
|
|
var handler = function(err, msg) { |
|
if (!(called ^ (called = true))) return; |
|
|
|
if (err) { |
|
self._stop(); |
|
record.error = err; |
|
record.message = null; |
|
} else { |
|
record.message = msg; |
|
} |
|
|
|
record.done = true; |
|
self._flushQueue(); |
|
}; |
|
|
|
try { |
|
this._session[this._method](message, handler); |
|
} catch (err) { |
|
handler(err); |
|
} |
|
}; |
|
|
|
Functor.prototype._stop = function() { |
|
this.pending = this._queue.length; |
|
this._stopped = true; |
|
}; |
|
|
|
Functor.prototype._flushQueue = function() { |
|
var queue = this._queue, record; |
|
|
|
while (queue.length > 0 && queue.peek().done) { |
|
record = queue.shift(); |
|
if (record.error) { |
|
this.pending = 0; |
|
queue.clear(); |
|
} else { |
|
this.pending -= 1; |
|
} |
|
record.callback.call(record.context, record.error, record.message); |
|
} |
|
}; |
|
|
|
module.exports = Functor;
|
|
|