@@ -33,3 +33,50 @@ helper('early close', function(client) {
33
33
} )
34
34
} )
35
35
} )
36
+
37
+
38
+ helper ( 'should not throw errors after early close' , function ( client ) {
39
+ it ( 'can be closed early without error' , function ( done ) {
40
+ var stream = new QueryStream ( 'SELECT * FROM generate_series(0, 2000) num' ) ;
41
+ var query = client . query ( stream ) ;
42
+ var fetchCount = 0 ;
43
+ var errorCount = 0 ;
44
+
45
+
46
+ function waitForErrors ( ) {
47
+
48
+ setTimeout ( function ( ) {
49
+ assert ( errorCount === 0 , 'should not throw a ton of errors' ) ;
50
+ done ( ) ;
51
+ } , 10 ) ;
52
+ }
53
+
54
+ // hack internal _fetch function to force query.close immediately after _fetch is called (simulating the race condition)
55
+ // race condition: if close is called immediately after _fetch is called, but before results are returned, errors are thrown
56
+ // when the fetch results are pushed to the readable stream after its already closed.
57
+ query . _fetch = ( function ( _fetch ) {
58
+ return function ( ) {
59
+
60
+ // wait for the second fetch. closing immediately after the first fetch throws an entirely different error :(
61
+ if ( fetchCount ++ === 0 ) {
62
+ return _fetch . apply ( this , arguments ) ;
63
+ }
64
+
65
+ var results = _fetch . apply ( this , arguments ) ;
66
+
67
+ query . close ( ) ;
68
+ waitForErrors ( ) ;
69
+
70
+ query . _fetch = _fetch ; // we're done with our hack, so restore the original _fetch function.
71
+
72
+ return results ;
73
+ }
74
+ } ( query . _fetch ) ) ;
75
+
76
+ query . on ( 'error' , function ( ) { errorCount ++ ; } ) ;
77
+
78
+ query . on ( 'readable' , function ( ) {
79
+ query . read ( ) ;
80
+ } ) ;
81
+ } ) ;
82
+ } ) ;
0 commit comments