Skip to content

Commit 7072a7d

Browse files
committed
Fix stdin chuck writing and add local perf cost
1 parent 524b630 commit 7072a7d

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,26 @@ go run ./dev/client tty bash
7070
go run ./dev/client notty ls
7171
```
7272

73+
### Local performance cost
74+
75+
Local `sh` through a local `wsep` connection
76+
77+
```shellscript
78+
$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time ./bin/client notty sh -c "cat > /dev/null"
79+
80+
95.4MiB 0:00:00 [ 269MiB/s] [ <=> ]
81+
./bin/client notty sh -c "cat > /dev/null" 0.32s user 0.31s system 31% cpu 2.019 total
82+
```
83+
84+
Local `sh` directly
85+
86+
```shell script
87+
$ head -c 100000000 /dev/urandom > /tmp/random; cat /tmp/random | pv | time sh -c "cat > /dev/null"
88+
89+
95.4MiB 0:00:00 [1.73GiB/s] [ <=> ]
90+
sh -c "cat > /dev/null" 0.00s user 0.02s system 32% cpu 0.057 total
91+
```
92+
7393
### Performance Goals
7494

7595
Test command

client.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ import (
1313
"nhooyr.io/websocket"
1414
)
1515

16+
const maxMessageSize = 64000
17+
1618
type remoteExec struct {
1719
conn *websocket.Conn
1820
}
1921

2022
// RemoteExecer creates an execution interface from a WebSocket connection.
2123
func RemoteExecer(conn *websocket.Conn) Execer {
24+
conn.SetReadLimit(maxMessageSize)
2225
return remoteExec{conn: conn}
2326
}
2427

@@ -94,7 +97,21 @@ func (r remoteStdin) Write(b []byte) (int, error) {
9497
return 0, err
9598
}
9699
stdinWriter := proto.WithHeader(r.conn, headerByt)
97-
return stdinWriter.Write(b)
100+
101+
maxBodySize := maxMessageSize - len(headerByt) - 1
102+
var nn int
103+
for len(b) > maxMessageSize {
104+
n, err := stdinWriter.Write(b[:maxBodySize])
105+
nn += n
106+
if err != nil {
107+
return nn, err
108+
}
109+
b = b[maxBodySize:]
110+
}
111+
112+
n, err := stdinWriter.Write(b)
113+
nn += n
114+
return nn, err
98115
}
99116

100117
func (r remoteStdin) Close() error {

server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
// The execer may be another wsep connection for chaining.
2121
// Use LocalExecer for local command execution.
2222
func Serve(ctx context.Context, c *websocket.Conn, execer Execer) error {
23+
c.SetReadLimit(maxMessageSize)
2324
var (
2425
header proto.Header
2526
process Process

0 commit comments

Comments
 (0)