diff --git a/packages/phoenix/packages/pty/exports.js b/packages/phoenix/packages/pty/exports.js index bbab56ef..da317532 100644 --- a/packages/phoenix/packages/pty/exports.js +++ b/packages/phoenix/packages/pty/exports.js @@ -34,22 +34,25 @@ export class BetterReader { const chunk = await this.getChunk_(); - if ( ! opt_buffer ) { + if ( ! opt_buffer || ! chunk ) { return chunk; } this.chunks_.push(chunk); while ( this.getTotalBytesReady_() < opt_buffer.length ) { - this.chunks_.push(await this.getChunk_()) + const read_chunk = await this.getChunk_(); + if ( ! read_chunk ) { + break; + } + this.chunks_.push(read_chunk); } - // TODO: need to handle EOT condition in this loop let offset = 0; - for (;;) { + while ( this.chunks_.length > 0 && offset < opt_buffer.length ) { let item = this.chunks_.shift(); if ( item === undefined ) { - throw new Error('calculation is wrong') + break; } if ( offset + item.length > opt_buffer.length ) { const diff = opt_buffer.length - offset; @@ -58,16 +61,16 @@ export class BetterReader { } opt_buffer.set(item, offset); offset += item.length; - - if ( offset == opt_buffer.length ) break; } - // return opt_buffer.length; + return offset; } async getChunk_() { if ( this.chunks_.length === 0 ) { - const { value } = await this.delegate.read(); + const { value } = await this.delegate.read().catch( ( err ) => { + return {}; + }); return value; } @@ -87,6 +90,11 @@ export class BetterReader { getTotalBytesReady_ () { return this.chunks_.reduce((sum, chunk) => sum + chunk.length, 0); } + + async releaseLock() { + console.log('cancelling betterreader, delegate is', this.delegate); + await this.delegate.releaseLock(); + } } /** diff --git a/packages/phoenix/src/ansi-shell/pipeline/Coupler.js b/packages/phoenix/src/ansi-shell/pipeline/Coupler.js index 2845be3a..b66af605 100644 --- a/packages/phoenix/src/ansi-shell/pipeline/Coupler.js +++ b/packages/phoenix/src/ansi-shell/pipeline/Coupler.js @@ -24,7 +24,9 @@ export class Coupler { Does not close the write stream when the read stream is closed. ` - constructor (source, target) { + constructor (source, target, debug) { + this.debug = debug || false; + console.log('creating coupler. source is', this.source); this.source = source; this.target = target; this.on_ = true; @@ -39,8 +41,9 @@ export class Coupler { on () { this.on_ = true; } close () { + if (this.debug) console.log('closing coupler. source is', this.source); + this.source.releaseLock(); this.closed_.resolve({ - value: undefined, done: true, }); } diff --git a/packages/phoenix/src/ansi-shell/pipeline/Pipeline.js b/packages/phoenix/src/ansi-shell/pipeline/Pipeline.js index 27ae2c56..a6507c2b 100644 --- a/packages/phoenix/src/ansi-shell/pipeline/Pipeline.js +++ b/packages/phoenix/src/ansi-shell/pipeline/Pipeline.js @@ -203,7 +203,7 @@ export class PreparedCommand { } const internal_input_pipe = new Pipe(); - const valve = new Coupler(in_, internal_input_pipe.in); + const valve = new Coupler(in_, internal_input_pipe.in, true); in_ = internal_input_pipe.out; // simple naive implementation for now diff --git a/packages/phoenix/src/ansi-shell/readline/readline.js b/packages/phoenix/src/ansi-shell/readline/readline.js index e7f816d2..9f8e69c7 100644 --- a/packages/phoenix/src/ansi-shell/readline/readline.js +++ b/packages/phoenix/src/ansi-shell/readline/readline.js @@ -57,7 +57,10 @@ const ReadlineProcessorBuilder = builder => builder const { locals, externs } = ctx; const byteBuffer = new Uint8Array(1); - await externs.in_.read(byteBuffer); + const bytesRead = await externs.in_.read(byteBuffer); + if (bytesRead !== 1) { + console.warn('Failed to read byte in get-byte state of readline'); + } locals.byteBuffer = byteBuffer; locals.byte = byteBuffer[0]; })