@@ -44,6 +44,7 @@ var SocketCluster = function (options) {
4444 self . EVENT_WORKER_CLUSTER_EXIT = 'workerClusterExit' ;
4545
4646 self . _pendingResponseHandlers = { } ;
47+ self . workerClusterMessageBuffer = [ ] ;
4748
4849 self . _errorAnnotations = {
4950 'EADDRINUSE' : 'Failed to bind to a port because it was already used by another process.'
@@ -125,6 +126,7 @@ SocketCluster.prototype._init = function (options) {
125126
126127 self . _active = false ;
127128 self . workerCluster = null ;
129+ self . isWorkerClusterReady = false ;
128130
129131 self . _colorCodes = {
130132 red : 31 ,
@@ -388,9 +390,11 @@ SocketCluster.prototype._logObject = function (obj, objType, time) {
388390
389391SocketCluster . prototype . _convertValueToUnknownError = function ( err , origin ) {
390392 if ( err && typeof err == 'object' ) {
391- // If err has neither a stack or message property
392- // then the error message will be the JSON stringified object.
393- if ( ! err . message && ! err . stack ) {
393+ if ( err . message || err . stack ) {
394+ err = scErrors . hydrateError ( err , true ) ;
395+ } else {
396+ // If err has neither a stack nor a message property
397+ // then the error message will be the JSON stringified object.
394398 var errorMessage ;
395399 try {
396400 errorMessage = JSON . stringify ( err ) ;
@@ -489,6 +493,8 @@ SocketCluster.prototype._workerWarningHandler = function (workerPid, warning) {
489493SocketCluster . prototype . _workerClusterReadyHandler = function ( ) {
490494 var self = this ;
491495
496+ this . isWorkerClusterReady = true ;
497+
492498 if ( ! this . _active ) {
493499 if ( this . options . rebootOnSignal ) {
494500 process . on ( 'SIGUSR2' , function ( ) {
@@ -512,6 +518,8 @@ SocketCluster.prototype._workerClusterReadyHandler = function () {
512518 this . _logDeploymentDetails ( ) ;
513519 }
514520
521+ this . _flushWorkerClusterMessageBuffer ( ) ;
522+
515523 var workerClusterInfo = {
516524 pid : this . workerCluster . pid ,
517525 childProcess : this . workerCluster
@@ -538,6 +546,8 @@ SocketCluster.prototype._workerStartHandler = function (workerInfo, signal) {
538546} ;
539547
540548SocketCluster . prototype . _handleWorkerClusterExit = function ( errorCode , signal ) {
549+ this . isWorkerClusterReady = false ;
550+
541551 var workerClusterInfo = {
542552 pid : this . workerCluster . pid ,
543553 code : errorCode ,
@@ -591,6 +601,7 @@ SocketCluster.prototype._launchWorkerCluster = function () {
591601 }
592602
593603 this . workerCluster = fork ( __dirname + '/lib/workercluster.js' , process . argv . slice ( 2 ) , execOptions ) ;
604+ this . isWorkerClusterReady = false ;
594605
595606 var workerOpts = this . _cloneObject ( this . options ) ;
596607 workerOpts . paths = this . _paths ;
@@ -631,7 +642,7 @@ SocketCluster.prototype._launchWorkerCluster = function () {
631642 self . _workerClusterErrorHandler ( m . data . pid , m . data . error ) ;
632643 }
633644 } else if ( m . type == 'warning' ) {
634- var warning = scErrors . hydrateError ( m . data . error ) ;
645+ var warning = scErrors . hydrateError ( m . data . error , true ) ;
635646 self . _workerWarningHandler ( m . data . workerPid , warning ) ;
636647 } else if ( m . type == 'ready' ) {
637648 self . _workerClusterReadyHandler ( ) ;
@@ -640,17 +651,18 @@ SocketCluster.prototype._launchWorkerCluster = function () {
640651 } else if ( m . type == 'workerExit' ) {
641652 self . _workerExitHandler ( m . data ) ;
642653 } else if ( m . type == 'workerMessage' ) {
643- self . emit ( 'workerMessage' , m . workerId , m . data , function ( data ) {
654+ self . emit ( 'workerMessage' , m . workerId , m . data , function ( err , data ) {
644655 if ( m . cid ) {
645- self . respondToWorker ( data , m . workerId , m . cid ) ;
656+ self . respondToWorker ( err , data , m . workerId , m . cid ) ;
646657 }
647658 } ) ;
648- } else if ( m . type == 'workerResponse' ) {
659+ } else if ( m . type == 'workerResponse' || m . type == 'workerClusterResponse' ) {
649660 var responseHandler = self . _pendingResponseHandlers [ m . rid ] ;
650661 if ( responseHandler ) {
651662 clearTimeout ( responseHandler . timeout ) ;
652663 delete self . _pendingResponseHandlers [ m . rid ] ;
653- responseHandler . callback ( null , m . data , m . workerId ) ;
664+ var properError = scErrors . hydrateError ( m . error , true ) ;
665+ responseHandler . callback ( properError , m . data , m . workerId ) ;
654666 }
655667 }
656668 } ) ;
@@ -662,11 +674,15 @@ SocketCluster.prototype._launchWorkerCluster = function () {
662674 this . emit ( this . EVENT_WORKER_CLUSTER_START , workerClusterInfo ) ;
663675
664676 this . workerCluster . on ( 'exit' , this . _handleWorkerClusterExit . bind ( this ) ) ;
677+ this . workerCluster . on ( 'disconnect' , function ( ) {
678+ self . isWorkerClusterReady = false ;
679+ } ) ;
665680} ;
666681
667- SocketCluster . prototype . respondToWorker = function ( data , workerId , rid ) {
682+ SocketCluster . prototype . respondToWorker = function ( err , data , workerId , rid ) {
668683 this . workerCluster . send ( {
669684 type : 'masterResponse' ,
685+ error : scErrors . dehydrateError ( err , true ) ,
670686 data : data ,
671687 rid : rid
672688 } ) ;
@@ -727,6 +743,7 @@ SocketCluster.prototype._start = function () {
727743 expiryAccuracy : self . _dataExpiryAccuracy ,
728744 downgradeToUser : self . options . downgradeToUser ,
729745 processTermTimeout : self . options . processTermTimeout ,
746+ ipcAckTimeout : self . options . ipcAckTimeout ,
730747 brokerOptions : self . options ,
731748 appBrokerControllerPath : self . _paths . appBrokerControllerPath ,
732749 appInitControllerPath : self . _paths . appInitControllerPath
@@ -750,15 +767,16 @@ SocketCluster.prototype._start = function () {
750767 self . emit ( self . EVENT_BROKER_EXIT , brokerInfo ) ;
751768 } ) ;
752769
753- self . _brokerEngineServer . on ( 'brokerMessage' , function ( brokerId , data ) {
754- self . emit ( 'brokerMessage' , brokerId , data ) ;
770+ self . _brokerEngineServer . on ( 'brokerMessage' , function ( brokerId , data , callback ) {
771+ self . emit ( 'brokerMessage' , brokerId , data , callback ) ;
755772 } ) ;
756773 } ;
757774
758775 launchBrokerEngine ( ) ;
759776} ;
760777
761778SocketCluster . prototype . _createIPCResponseHandler = function ( callback ) {
779+ var self = this ;
762780 var cid = uuid . v4 ( ) ;
763781
764782 var responseTimeout = setTimeout ( function ( ) {
@@ -776,6 +794,15 @@ SocketCluster.prototype._createIPCResponseHandler = function (callback) {
776794 return cid ;
777795} ;
778796
797+ SocketCluster . prototype . _flushWorkerClusterMessageBuffer = function ( ) {
798+ var self = this ;
799+
800+ this . workerClusterMessageBuffer . forEach ( function ( messagePacket ) {
801+ self . workerCluster . send ( messagePacket ) ;
802+ } ) ;
803+ this . workerClusterMessageBuffer = [ ] ;
804+ } ;
805+
779806SocketCluster . prototype . sendToWorker = function ( workerId , data , callback ) {
780807 var self = this ;
781808
@@ -788,11 +815,15 @@ SocketCluster.prototype.sendToWorker = function (workerId, data, callback) {
788815 if ( callback ) {
789816 messagePacket . cid = this . _createIPCResponseHandler ( callback ) ;
790817 }
791- this . workerCluster . send ( messagePacket ) ;
818+ this . workerClusterMessageBuffer . push ( messagePacket ) ;
819+
820+ if ( this . isWorkerClusterReady ) {
821+ this . _flushWorkerClusterMessageBuffer ( ) ;
822+ }
792823} ;
793824
794825SocketCluster . prototype . sendToBroker = function ( brokerId , data , callback ) {
795- this . _brokerEngineServer . sendToBroker ( brokerId , data ) ;
826+ this . _brokerEngineServer . sendToBroker ( brokerId , data , callback ) ;
796827} ;
797828
798829// The options object is optional and can have two boolean fields:
0 commit comments