@@ -33,3 +33,68 @@ helper('early close', function(client) {
33
33
} )
34
34
} )
35
35
} )
36
+
37
+ helper ( 'should not throw errors after early close' , function ( client ) {
38
+ it ( 'can be closed early without error' , function ( done ) {
39
+ var stream = new QueryStream ( 'SELECT * FROM generate_series(0, 2000) num' ) ;
40
+ var query = client . query ( stream ) ;
41
+ var fetchCount = 0 ;
42
+ var errorCount = 0 ;
43
+
44
+
45
+ function waitForErrors ( ) {
46
+
47
+ setTimeout ( function ( ) {
48
+ assert ( errorCount === 0 , 'should not throw a ton of errors' ) ;
49
+ done ( ) ;
50
+ } , 10 ) ;
51
+ }
52
+
53
+ // hack internal _fetch function to force query.close immediately after _fetch is called (simulating the race condition)
54
+ // race condition: if close is called immediately after _fetch is called, but before results are returned, errors are thrown
55
+ // when the fetch results are pushed to the readable stream after its already closed.
56
+ query . _fetch = ( function ( _fetch ) {
57
+ return function ( ) {
58
+
59
+ // wait for the second fetch. closing immediately after the first fetch throws an entirely different error :(
60
+ if ( fetchCount ++ === 0 ) {
61
+ return _fetch . apply ( this , arguments ) ;
62
+ }
63
+
64
+ var results = _fetch . apply ( this , arguments ) ;
65
+
66
+ query . close ( ) ;
67
+ waitForErrors ( ) ;
68
+
69
+ query . _fetch = _fetch ; // we're done with our hack, so restore the original _fetch function.
70
+
71
+ return results ;
72
+ }
73
+ } ( query . _fetch ) ) ;
74
+
75
+ query . on ( 'error' , function ( ) { errorCount ++ ; } ) ;
76
+
77
+ query . on ( 'readable' , function ( ) {
78
+ query . read ( ) ;
79
+ } ) ;
80
+ } ) ;
81
+ } ) ;
82
+
83
+ helper ( 'close callback' , function ( client ) {
84
+ it ( 'notifies an optional callback when the conneciton is closed' , function ( done ) {
85
+ var stream = new QueryStream ( 'SELECT * FROM generate_series(0, $1) num' , [ 10 ] , { batchSize : 2 , highWaterMark : 2 } ) ;
86
+ var query = client . query ( stream ) ;
87
+ query . once ( 'readable' , function ( ) { // only reading once
88
+ query . read ( ) ;
89
+ } ) ;
90
+ query . once ( 'readable' , function ( ) {
91
+ query . close ( function ( ) {
92
+ // nothing to assert. This test will time out if the callback does not work.
93
+ done ( ) ;
94
+ } ) ;
95
+ } ) ;
96
+ query . on ( 'close' , function ( ) {
97
+ assert ( false , "close event should not fire" ) ; // no close event because we did not read to the end of the stream.
98
+ } ) ;
99
+ } ) ;
100
+ } ) ;
0 commit comments