Skip to content

feat(net): named pipe support via Deno.pipe#29308

Closed
CyanChanges wants to merge 17 commits intodenoland:mainfrom
CyanChanges:pipes
Closed

feat(net): named pipe support via Deno.pipe#29308
CyanChanges wants to merge 17 commits intodenoland:mainfrom
CyanChanges:pipes

Conversation

@CyanChanges
Copy link
Copy Markdown
Contributor

@CyanChanges CyanChanges commented May 15, 2025

close #10244

Support Named Pipes via Deno.pipe

todos

@CyanChanges
Copy link
Copy Markdown
Contributor Author

image

Confirmed!
Works in Windows now!

(I spent a total of $5 on GCP for a Windows machine 😢)

@CyanChanges
Copy link
Copy Markdown
Contributor Author

Working on the Windows support for the deno_node PipeWrap .
image

@CyanChanges
Copy link
Copy Markdown
Contributor Author

CyanChanges commented May 19, 2025

Help Wanted

I encountered an issue when working on the node compat:

import * as net from 'node:net'

// I have a server listening on this pipe
// ```ts
// const pipe = Deno.pipe.listen({ path: "\\\\.\\pipe\\mypipe1", kind: "windows", pipeMode: "byte" })
// const ab = new Uint8Array(32)
// await pipe.read(ab); // didn't resolve, it resolve to null after the other side closed :skull: 
// ```
const conn = new net.createConnection({ path: "\\\\.\\pipe\\mypipe1" }) 
conn.write("something") // `true`, but do nothing

// if you await here, it will stuck here
/*await */ Deno[Deno.internal].core.write(
  /* 
  If you createConnection immediately after start, 
  the pipe resource should be assigned a rid of 3
  */ 
  3, 
  new TextEncoder().encode("test")
)

I tried to write it directly via Resource Id, but the promise never resolves,
instead, it rejects after the resource closed 😢

The read still works tho, no idea why.

image

The Problem Only Appear In Windows (Because the issue aim to support node:net.createConnection when using Windows with named pipe)

@nathanwhit nathanwhit added the ci-draft Run the CI on draft PRs. label May 23, 2025
Copy link
Copy Markdown
Member

@nathanwhit nathanwhit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, the implementation looks reasonable to me. I'm less sure about the public API changes and the pipe_wrap changes for windows. The pipe_wrap changes seem ok at a glance.

I think the team will have to discuss the new API, and then go from there.

@CyanChanges CyanChanges force-pushed the pipes branch 5 times, most recently from eecec1c to 6929148 Compare May 24, 2025 09:51
@bartlomieju bartlomieju added this to the 2.4.0 milestone May 27, 2025
@CyanChanges CyanChanges force-pushed the pipes branch 2 times, most recently from 30ae7d5 to a08662d Compare June 1, 2025 06:14
@CyanChanges CyanChanges force-pushed the pipes branch 2 times, most recently from 041f75a to dea1d83 Compare June 23, 2025 03:33
@CyanChanges CyanChanges marked this pull request as ready for review June 23, 2025 09:08
@CyanChanges CyanChanges requested a review from nathanwhit June 23, 2025 09:20
@CyanChanges
Copy link
Copy Markdown
Contributor Author

Node compat is kinda broken still, but I wonder if the Deno.pipe API is okay?

@kt3k
Copy link
Copy Markdown
Contributor

kt3k commented Jun 23, 2025

Is this Deno.pipe namespace aligned with the rest of Deno APIs? I think we usually express this kind of variation as transport option of Deno.connect. Deno.pipe namespace looks like random deviation from the existing API design to me.

@CyanChanges
Copy link
Copy Markdown
Contributor Author

CyanChanges commented Jun 23, 2025

Is this Deno.pipe namespace aligned with the rest of Deno APIs? I think we usually express this kind of variation as transport option of Deno.connect. Deno.pipe namespace looks like random deviation from the existing API design to me.

TL;DR Overloading the existing API would be a mess, and complicated, so I decided to create a seperate Deno.pipe for this.

Problem needs to consider if merging this to existing API

No accept in pipe

Unix pipes doesn't have the thing that allow handle "connections" independently
while Windows Named pipe does allow multi connection, but it doesn't come with a accept. Instead, it seems require to call CreateNamedPipe several times(?)

So things like returning a PipeConn in Listener<PipeConn, string> is not very possible.

Also, Windows and Unix interfaces are pretty different,
so needs to consider whether making two separate transport for Windows and Unix
or make them all transport: 'pipe'

No, at the beginning. I considered just make this a transport of Deno.connect and Deno.listen
image

But, after considering difference between platforms:

How it works

  • windows: more like unix domain socket, allow undirectional or bidirectional, there is also a pipe_mode that allow specify either message (datagram) or byte (stream)
  • unix: just a directional pipe

Extra work needed

  • windows: you need to explicit do a Connect, to accept one client (in tokio, it's a async fn)
  • unix: no need of accept

Similarly
but differ from other deno_net APIs

Both windows and unix don't have things like accept, reusing existing Conn class is going to be hard

So
Overloading the existing API would be a mess, and complicated, so I decided to create a seperate Deno.pipe for this.

image

@kt3k
Copy link
Copy Markdown
Contributor

kt3k commented Jun 23, 2025

Ok. Thanks for the clarification

@CyanChanges
Copy link
Copy Markdown
Contributor Author

This PR currently fixes compatibility with the following packages:

  • node-notifyer

The following packages still do not work properly:

  • discord-rpc
  • node-pty

yeah, somehow after put Deno.pipe to PipeWrap,it stopped accepting writes, so these packages is still broken, node-notifier somehow doesn't require bidirectional communication so it's fine

@CyanChanges
Copy link
Copy Markdown
Contributor Author

CyanChanges commented Jun 26, 2025

This PR currently fixes compatibility with the following packages:

  • node-notifyer

The following packages still do not work properly:

  • discord-rpc
  • node-pty

node-pty relies on node:fs.open pipe directly, which somehow broken when opening pipe, i guess it's better to do that follow up, not in this PR.

@bartlomieju bartlomieju modified the milestones: 2.4.0, 2.5.0 Jun 26, 2025
@steve02081504
Copy link
Copy Markdown

steve02081504 commented Jun 27, 2025

we still needs fs.* stuff's pipe support, but I guess this pr is already able to marge :)

  • discord-rpc: needs fs.existsSync's pipe support
  • node-pty: needs fs.openSync's pipe support

@CyanChanges
Copy link
Copy Markdown
Contributor Author

Guess it would be better to move PipeWrap to the Rust side

@CyanChanges
Copy link
Copy Markdown
Contributor Author

#31624

I think it should be a Deno API for named pipes for all platforms tho, but anyways

bartlomieju pushed a commit that referenced this pull request Dec 19, 2025
Co-authored-by:  Cyan Changes <contact@cyans.me>

Add support to Pipe.prototype.listen, Pipe.prototype.connect for windows
with named pipes.
Also support to Pipe.prototype.open for unix.

Alternative of #29308, but without
`Deno:pipe`.
Only with node compatibilities.


Solution for:
#25867
#28332
#31032


Maybe related:
#10244


I tested the Nuxt and Nx, they are working fine on Windows now.
I also tested node-pty, and it's working on Unix.

Co-authored-by: Cyan Changes <contact@cyans.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-draft Run the CI on draft PRs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for Named Pipes in Deno.connect Not implemented: Pipe.prototype.connect Uncaught Error: Not implemented: Pipe.prototype.listen - Windows

6 participants