grpc / grpc-node

gRPC for Node.js
https://grpc.io
Apache License 2.0
4.44k stars 640 forks source link

windows woes #2099

Open travisghansen opened 2 years ago

travisghansen commented 2 years ago

Problem description

I have 2 use-cases:

Are these 2 use-cases even possible currently? The link below seems to indicate it should but maybe not, or maybe I'm just doing something wrong in my configuration/setup?

When connecting to a named pipe it appears to detect the file appropriately etc and even send data but seemingly the named pipe is just ignoring the data.

node .\dev\csi-proxy.js
grpc implementation: @grpc/grpc-js
C:\Users\Administrator\Downloads\democratic-csi\csi_proxy_proto
csi-proxy request Filesystem/PathExists - data: {"path":"C:\\csi"}
NET 3448: createConnection [
  { path: '//./pipe/csi-proxy-filesystem-v1' },
  null,
  [Symbol(normalizedArgs)]: true
]
NET 3448: pipe true //./pipe/csi-proxy-filesystem-v1
HTTP2 3448: Http2Session client: created
(node:3448) Warning: Setting the NODE_DEBUG environment variable to 'http2' can expose sensitive data (such as passwords, tokens and authentication headers) in the resulting log.
(Use `node --trace-warnings ...` to show where the warning was created)
NET 3448: afterConnect
HTTP2 3448: Http2Session client: setting up session handle
Http2Session client (38) session created
Http2Session client (38) i/o stream consumed
HTTP2 3448: Http2Session client: sending settings
HTTP2 3448: Http2Session client: submitting settings
Http2Session client (38) scheduling write
STREAM 3448: read 0
STREAM 3448: need readable false
STREAM 3448: length less than watermark true
STREAM 3448: do read
NET 3448: _read
NET 3448: Socket._handle.readStart
HTTP2 3448: Http2Session client: initiating request
HTTP2 3448: Http2Session client: connected, initializing request
Http2Session client (38) request submitted
Http2Priority: parent: 0, weight: 16, exclusive: no
Http2Session client (38) submitting request
Http2Session client (38) request submitted, new stream id 1
Http2Session client (38) refreshing state
Http2Session client (38) refreshing state
STREAM 3448: resume
HttpStream 1 (42) [Http2Session client (38)] queuing 1 buffers to send
STREAM 3448: resume false
STREAM 3448: read 0
STREAM 3448: need readable false
STREAM 3448: length less than watermark true
STREAM 3448: do read
HttpStream 1 (42) [Http2Session client (38)] reading starting
STREAM 3448: flow true
STREAM 3448: read undefined
STREAM 3448: need readable true
STREAM 3448: length less than watermark true
STREAM 3448: reading, ended or constructing false
HTTP2 3448: Http2Stream 1 [Http2Session client]: shutting down writable on last write
HttpStream 1 (42) [Http2Session client (38)] writable side shutdown
Http2Session client (38) sending pending data
Http2Session client (38) nghttp2 has 24 bytes to send
Http2Session client (38) nghttp2 has 9 bytes to send
Http2Session client (38) nghttp2 has 119 bytes to send
Http2Session client (38) reading outbound data for stream 1
Http2Session client (38) stream 1 has pending outbound data
Http2Session client (38) sending 13 bytes for data frame on stream 1
Http2Session client (38) no more data for stream 1
Http2Session client (38) nghttp2 has 13 bytes to send directly
Http2Session client (38) wants read? 1
########### client stalls here

For creating a server as a uds I simply cannot get the server to bind:

# various path styles
unix://C:/temp/testpipe C:/temp/testpipe
STREAM 8080: resume false
STREAM 8080: read 0
STREAM 8080: need readable true
STREAM 8080: length less than watermark true
STREAM 8080: do read
STREAM 8080: flow true
STREAM 8080: read undefined
STREAM 8080: need readable true
STREAM 8080: length less than watermark true
STREAM 8080: reading or ended false
NET 8080: setupListenHandle temp/testpipe -1 -1 0 undefined
NET 8080: setupListenHandle: create a handle
NET 8080: bind to temp/testpipe
E No address added out of total 1 resolved
Error: No address added out of total 1 resolved
    at bindResultPromise.then.errorString (C:\Users\Administrator\Downloads\democratic-csi\node_modules\@grpc\grpc-js\build\src\server.js:414:42)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

# various path styles
unix:///temp/testpipe /temp/testpipe
STREAM 5640: resume false
STREAM 5640: read 0
STREAM 5640: need readable true
STREAM 5640: length less than watermark true
STREAM 5640: do read
STREAM 5640: flow true
STREAM 5640: read undefined
STREAM 5640: need readable true
STREAM 5640: length less than watermark true
STREAM 5640: reading or ended false
NET 5640: setupListenHandle /temp/testpipe -1 -1 0 undefined
NET 5640: setupListenHandle: create a handle
NET 5640: bind to /temp/testpipe
E No address added out of total 1 resolved
Error: No address added out of total 1 resolved
    at bindResultPromise.then.errorString (C:\Users\Administrator\Downloads\democratic-csi\node_modules\@grpc\grpc-js\build\src\server.js:414:42)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

# binds correctly, but I don't want named pipe, want a 'real' uds
unix:////./pipe/csi.sock //./pipe/csi.sock
STREAM 3480: resume false
STREAM 3480: read 0
STREAM 3480: need readable true
STREAM 3480: length less than watermark true
STREAM 3480: do read
STREAM 3480: flow true
STREAM 3480: read undefined
STREAM 3480: need readable true
STREAM 3480: length less than watermark true
STREAM 3480: reading or ended false
NET 3480: setupListenHandle //./pipe/csi.sock -1 -1 0 undefined
NET 3480: setupListenHandle: create a handle
NET 3480: bind to //./pipe/csi.sock
NET 3480: onconnection

Reproduction steps

        await new Promise((resolve, reject) => {
          csiServer.bindAsync(
            bindSocket,
            grpc.ServerCredentials.createInsecure(),
            (err) => {
              if (err) {
                reject(err);
                return;
              }
              resolve();
            }
          );
        });

Environment

Additional context

https://github.com/grpc/grpc-node/pull/1244

murgatroid99 commented 2 years ago

I notice that the first log has the line

NET 3448: createConnection [
  { path: '//./pipe/csi-proxy-filesystem-v1' },
  null,
  [Symbol(normalizedArgs)]: true
]

But in the second log, none of the paths you tried to bind match that one. Maybe that is the problem. You should try binding unix:////./pipe/csi-proxy-filesystem-v1

I don't want named pipe, want a 'real' uds

You are using Windows. Unix Domain Sockets are a technology on Unix systems. As far as I understand, named pipes are the closest equivalent on Windows.

travisghansen commented 2 years ago

The connection is to a separate project: https://github.com/kubernetes-csi/csi-proxy (not my own service).

I'll gather up more info but afaik the other 'csi' drivers are using actual uds on windows. I'm trying to gather more info to be sure I understand that correctly. I can say that for sure go apps build and run on windows when using uds code but I could be missing something.

https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/

travisghansen commented 2 years ago

OK, have confirmed that the csi drivers written in go are indeed using 'real' uds on windows and not named pipes.

nicolasnoble commented 2 years ago

AF_UNIX on Windows is a fairly new feature that's been introduced in Windows 10. I don't think it has crept into the nodejs runtime yet, and I doubt it'll be, since they've been working around the notion using named pipes since basically forever.

In all cases, I'm fairly certain this is on the nodejs runtime to support, not on us.

travisghansen commented 2 years ago

Is it possible to write my own transport/dialer and plug it into the grpc-js stuff or that's not feasible?

murgatroid99 commented 2 years ago

No, there isn't a practical way to do that.

travisghansen commented 2 years ago

I seem to find the edge cases don't I...