Commit graph

16 commits

Author SHA1 Message Date
am3o
acce1f1fd9
refactor: change deprecated "io/ioutil" package to recommended "io" package 2024-02-17 12:47:22 +01:00
David Fifield
4ae63eccab Benchmark websocket.Conn Upgrade creation.
I had thought to set a buffer size of 2048, half the websocket package
default of 4096. But it turns out when you don't set a buffer size, the
websocket package reuses the HTTP server's read/write buffers, which
empirically already have a size of 2048.

	$ go test -bench=BenchmarkUpgradeBufferSize -benchmem -benchtime=5s
	BenchmarkUpgradeBufferSize/0-4                     25669            234566 ns/op           32604 B/op        113 allocs/op
	BenchmarkUpgradeBufferSize/128-4                   24739            238283 ns/op           24325 B/op        117 allocs/op
	BenchmarkUpgradeBufferSize/1024-4                  25352            238885 ns/op           28087 B/op        116 allocs/op
	BenchmarkUpgradeBufferSize/2048-4                  22660            234890 ns/op           32444 B/op        116 allocs/op
	BenchmarkUpgradeBufferSize/4096-4                  25668            232591 ns/op           41672 B/op        116 allocs/op
	BenchmarkUpgradeBufferSize/8192-4                  24908            240755 ns/op           59103 B/op        116 allocs/op
2022-11-16 13:48:34 -07:00
David Fifield
2321642f3c Hoist temporary buffers outside the loop.
Otherwise the buffers are re-allocated on every iteration, which is a
surprise to me. I thought the compiler would do this transformation
itself.

Now there is just one allocation per client←server read (one
messageReader) and two allocations per server←client read (one
messageReader and one messageWriter).

	$ go test -bench=BenchmarkReadWrite -benchmem -benchtime=5s
	BenchmarkReadWrite/c←s_150-4              481054             12849 ns/op          11.67 MB/s           8 B/op          1 allocs/op
	BenchmarkReadWrite/s←c_150-4              421809             14095 ns/op          10.64 MB/s          56 B/op          2 allocs/op
	BenchmarkReadWrite/c←s_3000-4             208564             28003 ns/op         107.13 MB/s          16 B/op          2 allocs/op
	BenchmarkReadWrite/s←c_3000-4             186320             30576 ns/op          98.12 MB/s         112 B/op          4 allocs/op
2022-11-16 13:48:34 -07:00
David Fifield
264425a488 Use io.CopyBuffer in websocketconn.readLoop.
This avoids io.Copy allocating a 32 KB buffer on every call.
https://cs.opensource.google/go/go/+/refs/tags/go1.19.1:src/io/io.go;l=416

	$ go test -bench=BenchmarkReadWrite -benchmem -benchtime=5s
	BenchmarkReadWrite/c←s_150-4              385740             15114 ns/op           9.92 MB/s        4104 B/op          3 allocs/op
	BenchmarkReadWrite/s←c_150-4              347070             16824 ns/op           8.92 MB/s        4152 B/op          4 allocs/op
	BenchmarkReadWrite/c←s_3000-4             190257             31581 ns/op          94.99 MB/s        8208 B/op          6 allocs/op
	BenchmarkReadWrite/s←c_3000-4             163233             34821 ns/op          86.16 MB/s        8304 B/op          8 allocs/op
2022-11-16 13:48:34 -07:00
David Fifield
3df514ae29 Call WriteMessage directly in websocketconn.Conn.Write.
In the client←server direction, this hits a fast path that avoids
allocating a messageWriter.
https://github.com/gorilla/websocket/blob/v1.5.0/conn.go#L760

Cuts the number of allocations in half in the client←server direction:

	$ go test -bench=BenchmarkReadWrite -benchmem -benchtime=5s
	BenchmarkReadWrite/c←s_150-4              597511             13358 ns/op          11.23 MB/s       33709 B/op          2 allocs/op
	BenchmarkReadWrite/s←c_150-4              474176             13756 ns/op          10.90 MB/s       34968 B/op          4 allocs/op
	BenchmarkReadWrite/c←s_3000-4             156488             36290 ns/op          82.67 MB/s       68673 B/op          5 allocs/op
	BenchmarkReadWrite/s←c_3000-4             190897             34719 ns/op          86.41 MB/s       69730 B/op          8 allocs/op
2022-11-16 13:48:34 -07:00
David Fifield
8cadcaee70 Benchmark for websocketconn.Conn read/write.
Current output:
	$ go test -bench=BenchmarkReadWrite -benchmem -benchtime=5s
	BenchmarkReadWrite/c←s_150-4              451840             13904 ns/op          10.79 MB/s       34954 B/op          4 allocs/op
	BenchmarkReadWrite/s←c_150-4              452560             16134 ns/op           9.30 MB/s       36378 B/op          4 allocs/op
	BenchmarkReadWrite/c←s_3000-4             202950             40846 ns/op          73.45 MB/s       69833 B/op          8 allocs/op
	BenchmarkReadWrite/s←c_3000-4             189262             37930 ns/op          79.09 MB/s       69768 B/op          8 allocs/op
2022-11-16 13:48:34 -07:00
trinity-1686a
5ef5142bb0 format using go-1.19 2022-10-09 21:15:50 +02:00
David Fifield
380b133155 Close internal Pipes in websocketconn.Conn Close.
Unless something externally called Write after Close, the
writeLoop(ws, pr2) goroutine would run forever, because nothing would
ever close pw2/pr2.
https://bugs.torproject.org/33367#comment:4
2020-02-18 14:10:47 -07:00
Arlo Breault
28cf70bb44 Remove unreachable code
go vet was complaining,

common/websocketconn/websocketconn.go:56:2: unreachable code
2020-02-08 10:12:43 -05:00
David Fifield
256959ca65 Implement net.Conn for websocketconn.Conn.
We had already implemented Read, Write, and Close. Pass RemoteAddr,
LocalAddr, SetReadDeadline, and SetWriteDeadline through to the
underlying *websocket.Conn. Implement SetDeadline by calling both
SetReadDeadline and SetWriteDeadline.

https://bugs.torproject.org/33144
2020-02-04 15:53:15 -07:00
David Fifield
01e28aa460 Rewrite websocketconn with synchronous pipes.
Makes the following changes:
 * permits concurrent Read/Write/Close
 * converts certain CloseErrors into io.EOF

https://bugs.torproject.org/33144
2020-02-04 15:53:15 -07:00
David Fifield
5708a1d57b websocketconn tests.
https://bugs.torproject.org/33144
2020-02-04 15:53:15 -07:00
David Fifield
20ac2029fd Have websocketconn.New return a pointer.
This makes the return type satisfy the io.ReadWriteCloser interface
directly.
2020-01-30 10:18:23 -07:00
David Fifield
e47dd5e2b4 Remove some redundancy in websocketconn naming.
Rename websocketconn.WebSocketConn to websocketconn.Conn, and
       websocketconn.NewWebSocketConn to websocketconn.New

Following the guidelines at
https://blog.golang.org/package-names#TOC_3%2e
2020-01-30 10:18:23 -07:00
Arlo Breault
7092b2cb2c Revert abstracting copyloop 2019-11-21 19:33:39 -05:00
Arlo Breault
30b5ef8a9e Use gorilla websocket in proxy-go too
Trac: 32465
2019-11-20 19:33:28 -05:00