123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- '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;
|