@@ -25,12 +25,14 @@ const makeStateMachine = require('../utils').makeStateMachine;
25
25
const DISCONNECTED = 'disconnected' ;
26
26
const CONNECTING = 'connecting' ;
27
27
const CONNECTED = 'connected' ;
28
+ const DRAINING = 'draining' ;
28
29
const DESTROYING = 'destroying' ;
29
30
const DESTROYED = 'destroyed' ;
30
31
const stateTransition = makeStateMachine ( {
31
- [ DISCONNECTED ] : [ CONNECTING , DESTROYING , DISCONNECTED ] ,
32
- [ CONNECTING ] : [ CONNECTING , DESTROYING , CONNECTED , DISCONNECTED ] ,
33
- [ CONNECTED ] : [ CONNECTED , DISCONNECTED , DESTROYING ] ,
32
+ [ DISCONNECTED ] : [ CONNECTING , DRAINING , DISCONNECTED ] ,
33
+ [ CONNECTING ] : [ CONNECTING , CONNECTED , DRAINING , DISCONNECTED ] ,
34
+ [ CONNECTED ] : [ CONNECTED , DISCONNECTED , DRAINING ] ,
35
+ [ DRAINING ] : [ DRAINING , DESTROYING , DESTROYED ] ,
34
36
[ DESTROYING ] : [ DESTROYING , DESTROYED ] ,
35
37
[ DESTROYED ] : [ DESTROYED ]
36
38
} ) ;
@@ -270,7 +272,7 @@ function connectionFailureHandler(pool, event, err, conn) {
270
272
271
273
// No more socket available propegate the event
272
274
if ( pool . socketCount ( ) === 0 ) {
273
- if ( pool . state !== DESTROYED && pool . state !== DESTROYING ) {
275
+ if ( pool . state !== DESTROYED && pool . state !== DESTROYING && pool . state !== DRAINING ) {
274
276
stateTransition ( pool , DISCONNECTED ) ;
275
277
}
276
278
@@ -607,6 +609,8 @@ Pool.prototype.unref = function() {
607
609
608
610
// Destroy the connections
609
611
function destroy ( self , connections , options , callback ) {
612
+ stateTransition ( self , DESTROYING ) ;
613
+
610
614
eachAsync (
611
615
connections ,
612
616
( conn , cb ) => {
@@ -644,8 +648,8 @@ Pool.prototype.destroy = function(force, callback) {
644
648
return ;
645
649
}
646
650
647
- // Set state to destroyed
648
- stateTransition ( this , DESTROYING ) ;
651
+ // Set state to draining
652
+ stateTransition ( this , DRAINING ) ;
649
653
650
654
// Are we force closing
651
655
if ( force ) {
@@ -672,6 +676,14 @@ Pool.prototype.destroy = function(force, callback) {
672
676
673
677
// Wait for the operations to drain before we close the pool
674
678
function checkStatus ( ) {
679
+ if ( self . state === DESTROYED || self . state === DESTROYING ) {
680
+ if ( typeof callback === 'function' ) {
681
+ callback ( ) ;
682
+ }
683
+
684
+ return ;
685
+ }
686
+
675
687
flushMonitoringOperations ( self . queue ) ;
676
688
677
689
if ( self . queue . length === 0 ) {
@@ -795,17 +807,12 @@ Pool.prototype.write = function(command, options, cb) {
795
807
796
808
// Pool was destroyed error out
797
809
if ( this . state === DESTROYED || this . state === DESTROYING ) {
798
- // Callback with an error
799
- if ( cb ) {
800
- try {
801
- cb ( new MongoError ( 'pool destroyed' ) ) ;
802
- } catch ( err ) {
803
- process . nextTick ( function ( ) {
804
- throw err ;
805
- } ) ;
806
- }
807
- }
810
+ cb ( new MongoError ( 'pool destroyed' ) ) ;
811
+ return ;
812
+ }
808
813
814
+ if ( this . state === DRAINING ) {
815
+ cb ( new MongoError ( 'pool is draining, new operations prohibited' ) ) ;
809
816
return ;
810
817
}
811
818
@@ -938,7 +945,7 @@ function removeConnection(self, connection) {
938
945
}
939
946
940
947
function createConnection ( pool , callback ) {
941
- if ( pool . state === DESTROYED ) {
948
+ if ( pool . state === DESTROYED || pool . state === DESTROYING ) {
942
949
if ( typeof callback === 'function' ) {
943
950
callback ( new MongoError ( 'Cannot create connection when pool is destroyed' ) ) ;
944
951
}
@@ -979,7 +986,7 @@ function createConnection(pool, callback) {
979
986
}
980
987
981
988
// the pool might have been closed since we started creating the connection
982
- if ( pool . state === DESTROYED ) {
989
+ if ( pool . state === DESTROYED || pool . state === DESTROYING ) {
983
990
if ( typeof callback === 'function' ) {
984
991
callback ( new MongoError ( 'Pool was destroyed after connection creation' ) ) ;
985
992
}
@@ -1032,7 +1039,6 @@ function _execute(self) {
1032
1039
// operations
1033
1040
if ( self . connectingConnections > 0 ) {
1034
1041
self . executing = false ;
1035
- setTimeout ( ( ) => _execute ( self ) ( ) , 10 ) ;
1036
1042
return ;
1037
1043
}
1038
1044
@@ -1047,8 +1053,8 @@ function _execute(self) {
1047
1053
// Flush any monitoring operations
1048
1054
flushMonitoringOperations ( self . queue ) ;
1049
1055
1050
- // attempt to grow the pool
1051
- if ( totalConnections < self . options . size ) {
1056
+ // Try to create a new connection to execute stuck operation
1057
+ if ( totalConnections < self . options . size && self . queue . length > 0 ) {
1052
1058
createConnection ( self ) ;
1053
1059
}
1054
1060
0 commit comments