cell.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict';
  2. var Functor = require('./functor'),
  3. Pledge = require('./pledge');
  4. var Cell = function(tuple) {
  5. this._ext = tuple[0];
  6. this._session = tuple[1];
  7. this._functors = {
  8. incoming: new Functor(this._session, 'processIncomingMessage'),
  9. outgoing: new Functor(this._session, 'processOutgoingMessage')
  10. };
  11. };
  12. Cell.prototype.pending = function(direction) {
  13. var functor = this._functors[direction];
  14. if (!functor._stopped) functor.pending += 1;
  15. };
  16. Cell.prototype.incoming = function(error, message, callback, context) {
  17. this._exec('incoming', error, message, callback, context);
  18. };
  19. Cell.prototype.outgoing = function(error, message, callback, context) {
  20. this._exec('outgoing', error, message, callback, context);
  21. };
  22. Cell.prototype.close = function() {
  23. this._closed = this._closed || new Pledge();
  24. this._doClose();
  25. return this._closed;
  26. };
  27. Cell.prototype._exec = function(direction, error, message, callback, context) {
  28. this._functors[direction].call(error, message, function(err, msg) {
  29. if (err) err.message = this._ext.name + ': ' + err.message;
  30. callback.call(context, err, msg);
  31. this._doClose();
  32. }, this);
  33. };
  34. Cell.prototype._doClose = function() {
  35. var fin = this._functors.incoming,
  36. fout = this._functors.outgoing;
  37. if (!this._closed || fin.pending + fout.pending !== 0) return;
  38. if (this._session) this._session.close();
  39. this._session = null;
  40. this._closed.done();
  41. };
  42. module.exports = Cell;