denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
97.83k stars 5.39k forks source link

feature proposal: Deno builtin function & ops to create an anonymous pipe. #7586

Open PaulThompson opened 4 years ago

PaulThompson commented 4 years ago

I propose idea of an additional builtin function Deno.pipe to open a new anonymous pipe. The call result ultimately would provide two resource ids which could be used to assemble process pipelines.

The key benefit compared to alternatives:

Use case sketch:

// prepare a pipe: (proposed new function).
const anonpipe = await Deno.pipe();

// start a process (esp if it will produce a lot of stdout output)
const producer = Deno.run({cmd:['producer'], stdout: anonpipe[0].rid});

// start next process in a pipeline of processes:
const consumer = Deno.run({cmd:['consumer'], stdin: anonpipe[1].rid});

// await processes status' and close all etc

The proposed function could have types as follows:

function Deno.pipe(): Promise<[AnonPipe,AnonPipe]>;

/// (one end of) an anonymous pipe
class Deno.AnonPipe {
// properties and methods similar to Deno.File but omitting seek & seekSync
readonly rid: number;
write(p: Uint8Array): Promise<number>;
writeSync(p: Uint8Array): number;
read(p: Uint8Array): Promise<number | null>;
readSync(p: Uint8Array): number | null;
close(): void;
};

The implementation in rust would be to call one of the platform depdendent functions for create an anonymous pipe eg https://github.com/rust-lang/rust/blob/f4e4485a052857e5dd32ea29ceb7b1a8223e83cc/library/std/src/sys/unix/pipe.rs#L12

fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)>

or https://github.com/rust-lang/rust/blob/f4e4485a052857e5dd32ea29ceb7b1a8223e83cc/library/std/src/sys/windows/pipe.rs#L48 etc

Note:

solson commented 4 years ago

I think this would solve the problem in https://github.com/denoland/deno/issues/2494 — using OS-level pipes between the child processes (with no copying through the parent Deno process) would work exactly like shell piping, and when the writing process quits and closes its stdout, the reading process will detect this on its stdin the usual way.