@@ -162,6 +162,7 @@ class QUICStream
162
162
} ,
163
163
write : async ( chunk : Uint8Array ) => {
164
164
await this . streamSend ( chunk ) ;
165
+ void this . connection . send ( ) . catch ( ( ) => { } ) ;
165
166
} ,
166
167
close : async ( ) => {
167
168
// This gracefully closes, by sending a message at the end
@@ -170,11 +171,13 @@ class QUICStream
170
171
// If this itself results in an error, we can continue
171
172
// But continue to do the below
172
173
this . logger . info ( 'sending fin frame' ) ;
174
+ // This.sendFinishedProm.resolveP();
173
175
await this . streamSend ( new Uint8Array ( 0 ) , true ) . catch ( ( e ) => {
174
176
// Ignore send error if stream is already closed
175
177
if ( e . message !== 'send' ) throw e ;
176
178
} ) ;
177
179
await this . closeSend ( ) ;
180
+ void this . connection . send ( ) . catch ( ( ) => { } ) ;
178
181
} ,
179
182
abort : async ( reason ?: any ) => {
180
183
// Abort can be called even if there are writes are queued up
@@ -237,7 +240,7 @@ class QUICStream
237
240
this . writableController . error ( e ) ;
238
241
await this . closeSend ( true , e ) ;
239
242
}
240
- await this . connection . send ( ) ;
243
+ void this . connection . send ( ) . catch ( ( ) => { } ) ;
241
244
this . logger . debug ( 'waiting for underlying streams to finish' ) ;
242
245
this . isFinished ( ) ;
243
246
// We need to wait for the connection to finish before fully destroying
@@ -272,10 +275,11 @@ class QUICStream
272
275
// After reading it's possible the writer had a state change.
273
276
this . isSendFinished ( ) ;
274
277
if ( this . _recvPaused ) {
278
+ console . log ( 'SKIPPING!' ) ;
275
279
// Do nothing if we are paused
276
280
return ;
277
281
}
278
- void this . streamRecv ( ) ;
282
+ void this . streamRecv ( ) . catch ( ( ) => { } ) ;
279
283
}
280
284
281
285
/**
@@ -285,7 +289,7 @@ class QUICStream
285
289
@ready ( new errors . ErrorQUICStreamDestroyed ( ) , false , [ 'destroying' ] )
286
290
public write ( ) : void {
287
291
// Checking if writable has ended
288
- void this . isSendFinished ( ) ;
292
+ this . isSendFinished ( ) ;
289
293
if ( this . resolveWritableP != null ) {
290
294
this . resolveWritableP ( ) ;
291
295
}
@@ -314,7 +318,7 @@ class QUICStream
314
318
'Readable stream closed early with no reason' ,
315
319
) ;
316
320
this . readableController . error ( err ) ;
317
- void this . closeRecv ( true , err ) ;
321
+ void this . closeRecv ( true , err ) . catch ( ( ) => { } ) ;
318
322
}
319
323
}
320
324
return recvFinished ;
@@ -332,6 +336,7 @@ class QUICStream
332
336
} catch ( e ) {
333
337
// If the writable has ended, we need to close the writable.
334
338
// We need to do this in the background to keep this synchronous.
339
+ this . sendFinishedProm . resolveP ( ) ;
335
340
void this . processSendStreamError ( e , 'send' ) . then ( ( reason ) => {
336
341
if ( ! this . _sendClosed ) {
337
342
const err =
@@ -340,10 +345,10 @@ class QUICStream
340
345
'Writable stream closed early with no reason' ,
341
346
) ;
342
347
this . writableController . error ( err ) ;
343
- void this . closeSend ( true , err ) ;
348
+ void this . closeSend ( true , err ) . catch ( ( ) => { } ) ;
344
349
}
345
- this . sendFinishedProm . resolveP ( ) ;
346
350
} ) ;
351
+ this . logger . info ( 'send FINISHED' ) ;
347
352
return true ;
348
353
}
349
354
}
@@ -352,63 +357,63 @@ class QUICStream
352
357
const buf = Buffer . alloc ( 1024 ) ;
353
358
let recvLength : number , fin : boolean ;
354
359
this . logger . debug ( 'trying receiving' ) ;
355
- try {
356
- [ recvLength , fin ] = this . conn . streamRecv ( this . streamId , buf ) ;
357
- } catch ( e ) {
358
- if ( e . message === 'Done' ) {
359
- // When it is reported to be `Done`, it just means that there is no data to read
360
- // it does not mean that the stream is closed or finished
361
- // In such a case, we just ignore and continue
362
- // However after the stream is closed, then it would continue to return `Done`
363
- // This can only occur in 2 ways, either via the `fin`
364
- // or through an exception here where the stream reports an error
365
- // Since we don't call this method unless it is readable
366
- // This should never be reported... (this branch should be dead code)
367
- return ;
368
- } else {
369
- this . logger . info ( 'Stream reported: error' ) ;
370
- this . logger . error ( `Stream reported: error ${ e . message } ` ) ;
371
- // Signal receiving has ended
372
- this . recvFinishedProm . resolveP ( ) ;
373
- const reason = await this . processSendStreamError ( e , 'recv' ) ;
374
- if ( reason != null ) {
375
- // If it is `StreamReset(u64)` error, then the peer has closed
376
- // the stream, and we are receiving the error code
377
- this . readableController . error ( reason ) ;
378
- await this . closeRecv ( true , reason ) ;
360
+ while ( true ) {
361
+ try {
362
+ [ recvLength , fin ] = this . conn . streamRecv ( this . streamId , buf ) ;
363
+ } catch ( e ) {
364
+ if ( e . message === 'Done' ) {
365
+ // When it is reported to be `Done`, it just means that there is no data to read
366
+ // it does not mean that the stream is closed or finished
367
+ // In such a case, we just ignore and continue
368
+ // However after the stream is closed, then it would continue to return `Done`
369
+ // This can only occur in 2 ways, either via the `fin`
370
+ // or through an exception here where the stream reports an error
371
+ // Since we don't call this method unless it is readable
372
+ // This should never be reported... (this branch should be dead code)
373
+ return ;
379
374
} else {
380
- // If it is not a `StreamReset(u64)`, then something else broke
381
- // and we need to propagate the error up and down the stream
382
- this . readableController . error ( e ) ;
383
- await this . closeRecv ( true , e ) ;
375
+ this . logger . info ( 'Stream reported: error' ) ;
376
+ this . logger . error ( `Stream reported: error ${ e . message } ` ) ;
377
+ // Signal receiving has ended
378
+ this . recvFinishedProm . resolveP ( ) ;
379
+ if ( ! this . _recvClosed ) {
380
+ const reason = await this . processSendStreamError ( e , 'recv' ) ;
381
+ if ( reason != null ) {
382
+ // If it is `StreamReset(u64)` error, then the peer has closed
383
+ // the stream, and we are receiving the error code
384
+ this . readableController . error ( reason ) ;
385
+ await this . closeRecv ( true , reason ) ;
386
+ } else {
387
+ // If it is not a `StreamReset(u64)`, then something else broke
388
+ // and we need to propagate the error up and down the stream
389
+ this . readableController . error ( e ) ;
390
+ await this . closeRecv ( true , e ) ;
391
+ }
392
+ }
393
+ return ;
384
394
}
385
- return ;
386
395
}
387
- } finally {
388
- // Let's check if sending side has finished
389
- await this . connection . send ( ) ;
390
- }
391
396
392
- // If fin is true, then that means, the stream is CLOSED
393
- if ( fin ) {
394
- // This will render `stream.cancel` a noop
395
- this . logger . info ( 'Stream reported: fin' ) ;
396
- if ( ! this . _recvClosed ) this . readableController . close ( ) ;
397
- await this . closeRecv ( ) ;
398
- // Signal receiving has ended
399
- this . recvFinishedProm . resolveP ( ) ;
400
- return ;
401
- }
402
- // Only fin packets are 0 length, so we enqueue after checking fin
403
- if ( ! this . _recvClosed ) {
404
- this . readableController . enqueue ( buf . subarray ( 0 , recvLength ) ) ;
405
- }
406
- // Now we pause receiving if the queue is full
407
- if (
408
- this . readableController . desiredSize != null &&
409
- this . readableController . desiredSize <= 0
410
- ) {
411
- this . _recvPaused = true ;
397
+ // If fin is true, then that means, the stream is CLOSED
398
+ if ( fin ) {
399
+ // This will render `stream.cancel` a noop
400
+ this . logger . info ( 'Stream reported: fin' ) ;
401
+ if ( ! this . _recvClosed ) this . readableController . close ( ) ;
402
+ await this . closeRecv ( ) ;
403
+ // Signal receiving has ended
404
+ this . recvFinishedProm . resolveP ( ) ;
405
+ return ;
406
+ }
407
+ if ( ! this . _recvClosed ) {
408
+ this . readableController . enqueue ( buf . subarray ( 0 , recvLength ) ) ;
409
+ }
410
+ // Now we pause receiving if the queue is full
411
+ if (
412
+ this . readableController . desiredSize != null &&
413
+ this . readableController . desiredSize <= 0
414
+ ) {
415
+ this . _recvPaused = true ;
416
+ }
412
417
}
413
418
}
414
419
@@ -454,8 +459,6 @@ class QUICStream
454
459
throw e ;
455
460
}
456
461
}
457
- } finally {
458
- await this . connection . send ( ) ;
459
462
}
460
463
if ( sentLength < chunk . length ) {
461
464
const { p : writableP , resolveP : resolveWritableP } = utils . promise ( ) ;
@@ -478,6 +481,7 @@ class QUICStream
478
481
isError : boolean = false ,
479
482
reason ?: any ,
480
483
) : Promise < void > {
484
+ if ( isError ) this . logger . error ( reason . message ) ;
481
485
// Further closes are NOPs
482
486
if ( this . _recvClosed ) return ;
483
487
this . logger . info ( `Close Recv` ) ;
@@ -512,6 +516,7 @@ class QUICStream
512
516
isError : boolean = false ,
513
517
reason ?: any ,
514
518
) : Promise < void > {
519
+ if ( isError ) this . logger . error ( reason . message ) ;
515
520
// Further closes are NOPs
516
521
if ( this . _sendClosed ) return ;
517
522
this . logger . info ( `Close Send` ) ;
@@ -561,6 +566,39 @@ class QUICStream
561
566
}
562
567
return null ;
563
568
}
569
+
570
+ static checkStreamStates (
571
+ conn : Connection ,
572
+ streamId : number ,
573
+ message : string ,
574
+ logger : Logger ,
575
+ ) {
576
+ const fin = conn . streamFinished ( streamId ) ;
577
+ const read = conn . streamReadable ( streamId ) ;
578
+ let write : boolean | string ;
579
+ try {
580
+ write = conn . streamWritable ( streamId , 0 ) ;
581
+ } catch ( e ) {
582
+ write = e . message ;
583
+ }
584
+ let cap : number | string ;
585
+ try {
586
+ cap = conn . streamCapacity ( streamId ) ;
587
+ } catch ( e ) {
588
+ cap = e . message ;
589
+ }
590
+ let readIter = false ;
591
+ for ( const id of conn . readable ( ) ) {
592
+ if ( streamId === id ) readIter = true ;
593
+ }
594
+ let writeIter = false ;
595
+ for ( const id of conn . writable ( ) ) {
596
+ if ( streamId === id ) writeIter = true ;
597
+ }
598
+ logger . info (
599
+ `Stream states (${ message } ) iterRW(${ readIter } , ${ writeIter } ),finished(${ fin } ), read(${ read } ), write(${ write } ), capacity(${ cap } )` ,
600
+ ) ;
601
+ }
564
602
}
565
603
566
604
export default QUICStream ;
0 commit comments