File tree Expand file tree Collapse file tree 2 files changed +33
-0
lines changed
Expand file tree Collapse file tree 2 files changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -518,6 +518,18 @@ export default class FSExtentStore implements IExtentStore {
518518 let count : number = 0 ;
519519 let wsEnd = false ;
520520
521+ if ( ! rs . readable ) {
522+ this . logger . debug (
523+ `FSExtentStore:streamPipe() Readable stream is not readable, rejecting streamPipe.` ,
524+ contextId
525+ ) ;
526+ reject (
527+ new Error (
528+ `FSExtentStore:streamPipe() Readable stream is not readable.`
529+ ) ) ;
530+ return ;
531+ }
532+
521533 rs . on ( "data" , data => {
522534 count += data . length ;
523535 if ( ! ws . write ( data ) ) {
Original file line number Diff line number Diff line change @@ -47,4 +47,25 @@ describe("FSExtentStore", () => {
4747 let readable3 = await store . readExtent ( extent3 ) ;
4848 assert . strictEqual ( await readIntoString ( readable3 ) , "Test" ) ;
4949 } ) ;
50+
51+ it ( "should handle garbage collected input stream during appendExtent @loki" , async ( ) => {
52+ const store = new FSExtentStore ( metadataStore , DEFAULT_BLOB_PERSISTENCE_ARRAY , logger ) ;
53+ await store . init ( ) ;
54+
55+ const stream1 = Readable . from ( "Test" , { objectMode : false } ) ;
56+
57+ // From manual testing express.js it seems that if the request is aborted
58+ // before it is handled/listeners are set up, the stream is destroyed.
59+ // This simulates that behavior.
60+ stream1 . destroy ( ) ;
61+
62+ // Then we check that appendExtent handles the destroyed stream
63+ // gracefully/does not hang.
64+ try {
65+ await store . appendExtent ( stream1 ) ;
66+ assert . fail ( "Expected an error to be thrown due to destroyed stream" ) ;
67+ } catch ( err ) {
68+ assert . deepStrictEqual ( err . message , "FSExtentStore:streamPipe() Readable stream is not readable." ) ;
69+ }
70+ } ) ;
5071} ) ;
You can’t perform that action at this time.
0 commit comments