Skip to content

Commit

Permalink
perf: use synchronous writers more
Browse files Browse the repository at this point in the history
Should make it more responsive.
  • Loading branch information
dsherret committed Sep 14, 2022
1 parent bd60a22 commit b8402df
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 24 deletions.
8 changes: 4 additions & 4 deletions src/command_handler.ts
Expand Up @@ -2,10 +2,10 @@ import { ExecuteResult } from "./result.ts";

export type CommandPipeReader = "inherit" | "null" | Deno.Reader;

export interface CommandPipeWriter extends Deno.Writer {
write(p: Uint8Array): Promise<number>;
writeText(text: string): Promise<void>;
writeLine(text: string): Promise<void>;
export interface CommandPipeWriter extends Deno.WriterSync {
writeSync(p: Uint8Array): number;
writeText(text: string): void;
writeLine(text: string): void;
}

export interface CommandContext {
Expand Down
2 changes: 1 addition & 1 deletion src/deps.ts
Expand Up @@ -2,5 +2,5 @@ export * as colors from "https://deno.land/std@0.153.0/fmt/colors.ts";
export * as fs from "https://deno.land/std@0.153.0/fs/mod.ts";
export { Buffer } from "https://deno.land/std@0.153.0/io/buffer.ts";
export * as path from "https://deno.land/std@0.153.0/path/mod.ts";
export { readAll, writeAll } from "https://deno.land/std@0.153.0/streams/conversion.ts";
export { readAll, writeAllSync } from "https://deno.land/std@0.153.0/streams/conversion.ts";
export { RealEnvironment as DenoWhichRealEnvironment, which, whichSync } from "https://deno.land/x/which@0.2.1/mod.ts";
35 changes: 17 additions & 18 deletions src/pipes.ts
@@ -1,4 +1,4 @@
import { Buffer, writeAll } from "./deps.ts";
import { Buffer, writeAllSync } from "./deps.ts";

const encoder = new TextEncoder();

Expand All @@ -12,17 +12,17 @@ export type ShellPipeReader = "inherit" | "null" | Deno.Reader;
*/
export type ShellPipeWriterKind = "inherit" | "null" | "piped" | "inheritPiped";

export class NullPipeWriter implements Deno.Writer {
write(p: Uint8Array): Promise<number> {
return Promise.resolve(p.length);
export class NullPipeWriter implements Deno.WriterSync {
writeSync(p: Uint8Array): number {
return p.length;
}
}

export class ShellPipeWriter implements Deno.Writer {
export class ShellPipeWriter implements Deno.WriterSync {
#kind: ShellPipeWriterKind;
#inner: Deno.Writer;
#inner: Deno.WriterSync;

constructor(kind: ShellPipeWriterKind, inner: Deno.Writer) {
constructor(kind: ShellPipeWriterKind, inner: Deno.WriterSync) {
this.#kind = kind;
this.#inner = inner;
}
Expand All @@ -31,24 +31,24 @@ export class ShellPipeWriter implements Deno.Writer {
return this.#kind;
}

write(p: Uint8Array): Promise<number> {
return this.#inner.write(p);
writeSync(p: Uint8Array) {
return this.#inner.writeSync(p);
}

async writeText(text: string) {
return writeAll(this, encoder.encode(text));
writeText(text: string) {
return writeAllSync(this, encoder.encode(text));
}

async writeLine(text: string) {
writeLine(text: string) {
return this.writeText(text + "\n");
}
}

export class CapturingBufferWriter implements Deno.Writer {
export class CapturingBufferWriter implements Deno.WriterSync {
#buffer: Buffer;
#innerWriter: Deno.Writer;
#innerWriter: Deno.WriterSync;

constructor(innerWriter: Deno.Writer, buffer: Buffer) {
constructor(innerWriter: Deno.WriterSync, buffer: Buffer) {
this.#innerWriter = innerWriter;
this.#buffer = buffer;
}
Expand All @@ -57,9 +57,8 @@ export class CapturingBufferWriter implements Deno.Writer {
return this.#buffer;
}

async write(p: Uint8Array): Promise<number> {
const nWritten = await this.#innerWriter.write(p);
// sync is ok because Buffer is sync
writeSync(p: Uint8Array) {
const nWritten = this.#innerWriter.writeSync(p);
this.#buffer.writeSync(p.slice(0, nWritten));
return nWritten;
}
Expand Down
20 changes: 19 additions & 1 deletion src/shell.ts
Expand Up @@ -604,7 +604,7 @@ async function executeCommandArgs(commandArgs: string[], context: Context) {
}
// don't abort... ensure all of stdout/stderr is read in case the process
// exits before this finishes
await pipeReaderToWriter(reader, writer, new AbortController().signal);
await pipeReaderToWriterSync(reader, writer, new AbortController().signal);
}

async function pipeReaderToWriter(reader: Deno.Reader, writer: Deno.Writer, signal: AbortSignal) {
Expand All @@ -625,6 +625,24 @@ async function executeCommandArgs(commandArgs: string[], context: Context) {
}
}

async function pipeReaderToWriterSync(reader: Deno.Reader, writer: Deno.WriterSync, signal: AbortSignal) {
while (!signal.aborted) {
const buffer = new Uint8Array(1024);
const length = await reader.read(buffer);
if (length === 0 || length == null) {
break;
}
writeAll(buffer.subarray(0, length));
}

function writeAll(arr: Uint8Array) {
let nwritten = 0;
while (nwritten < arr.length && !signal.aborted) {
nwritten += writer.writeSync(arr.subarray(nwritten));
}
}
}

function getStdioStringValue(value: ShellPipeReader | ShellPipeWriterKind) {
if (value === "inheritPiped") {
return "piped";
Expand Down

0 comments on commit b8402df

Please sign in to comment.