Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions frameworks/uio-ws/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ module httparena/uio-ws

go 1.25.0

require github.com/urpc/uio v1.5.4
require github.com/urpc/uio v1.8.0

require (
github.com/klauspost/compress v1.20.1 // indirect
github.com/klauspost/compress v1.20.3 // indirect
github.com/libp2p/go-reuseport v0.4.0 // indirect
github.com/limpo1989/taskgo v1.5.0 // indirect
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 // indirect
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b // indirect
github.com/segmentio/asm v1.2.1 // indirect
golang.org/x/sys v0.44.0 // indirect
)
16 changes: 8 additions & 8 deletions frameworks/uio-ws/go.sum
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/klauspost/compress v1.20.1 h1:T7kKElXUMXrUJ2E9QhQhxFtcK5rPyLdsGZvdbLMPdiQ=
github.com/klauspost/compress v1.20.1/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/klauspost/compress v1.20.3 h1:zWNoFqq/lSuYQRim3dUXlXeA0IqwuZGicdG5ZTfY5j4=
github.com/klauspost/compress v1.20.3/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
github.com/limpo1989/taskgo v1.5.0 h1:xczgiyKl20SyWJ5OwH6CcYFMPliCTMUnRWXciRhegLc=
github.com/limpo1989/taskgo v1.5.0/go.mod h1:x3mZYu4EyiAGBqy/qENxNKr78yLgHfjPg58RJRXklmY=
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 h1:lcWAnrqr2nNfDiArwFNHCE4787Mw2tCdVSOXCru0/0E=
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b h1:OzNsuVdSWGwXvWKTtChx9ve89k4cFJ6NxYM4Aw4/f+E=
github.com/petermattis/goid v0.0.0-20260918085751-abfca077860b/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/urpc/uio v1.5.4 h1:jQveJ3I0G4z8ToDr30ClPo5GuwetNNpc4rvWF+QuuIk=
github.com/urpc/uio v1.5.4/go.mod h1:Jso/P2w3//g9d2ibEbFjDlqc/lLYBmh709BxKVfOhS8=
github.com/urpc/uio v1.8.0 h1:IIcIgcBkWkCbU1vgOXc+x+GNsnfRJnVceDhOLDncg7s=
github.com/urpc/uio v1.8.0/go.mod h1:bn53YZsTaT5E68M4bhGkE0jcYL6w0aKpj9dIA2fC5lI=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
Expand Down
22 changes: 12 additions & 10 deletions frameworks/uio-ws/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import (
"log"
"os"
"os/signal"
"runtime"
"syscall"

"github.com/urpc/uio"
"github.com/urpc/uio/uws"
)

Expand All @@ -22,21 +20,25 @@ func (echoHandler) OnOpen(*uws.Conn) {}
func (echoHandler) OnMessage(conn *uws.Conn, message uws.Message) {
switch message.Type {
case uws.TextMessage:
_ = conn.SendText(message.Payload)
_ = conn.SendText(message.Text())
case uws.BinaryMessage:
_ = conn.SendBinary(message.Payload)
_ = conn.SendBinary(message.Bytes())
}
}

func (echoHandler) OnClose(*uws.Conn, uws.CloseEvent) {}

func main() {
server := uws.NewServer(echoHandler{})
// One event loop per CPU: uio's default is four pollers, which leaves the
// cores of a benchmark host idle. A read round's replies leave coalesced
// in one sendmsg, and a send the socket refuses is finished by the next
// write turn without pausing the read.
server.Events = &uio.Events{Pollers: runtime.NumCPU()}
// uio's default pollers: one loop per four Ps, at most eight. More loops
// only add turn hand-offs, which short-lived connections pay repeatedly.
server := uws.NewServer(uws.Options{
Handler: echoHandler{},
// One listening socket per poller, spread by the kernel's SO_REUSEPORT
// hash: upgrades arrive on the same socket their connection's loop
// accepts from, which short-lived connections — every upgrade here is
// one — feel as one less cross-loop handoff.
ReusePort: true,
})

stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
Expand Down
2 changes: 1 addition & 1 deletion frameworks/uio-ws/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "experimental",
"mode": "standard",
"engine": "uio",
"description": "uws WebSocket echo on uio: the RFC 6455 handshake and frame parser run in the connection's own I/O task on uio's edge-triggered event loops, one per CPU, so each message is parsed from the buffer its task read into and echoed from that task with no goroutine per connection; a read round's replies leave coalesced in one sendmsg, and a send the socket refuses is finished by the next write turn without pausing the read. Default configuration otherwise.",
"description": "uws WebSocket echo on uio: the RFC 6455 handshake and frame parser run in the connection's own I/O task on uio's edge-triggered event loops, one per CPU, so each message is parsed from the buffer its task read into and echoed from that task with no goroutine per connection; a read round's replies leave coalesced in one sendmsg, and a send the socket refuses is finished by the next write turn without pausing the read. A SO_REUSEPORT listener group puts each upgrade on the loop that runs its connection. uio defaults otherwise.",
"repo": "https://github.com/urpc/uio",
"enabled": true,
"tests": [
Expand Down
2 changes: 1 addition & 1 deletion site/data/frameworks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,7 @@
},
"uio-ws": {
"dir": "uio-ws",
"description": "uws WebSocket echo on uio: the RFC 6455 handshake and frame parser run in the connection's own I/O task on uio's edge-triggered event loops, one per CPU, so each message is parsed from the buffer its task read into and echoed from that task with no goroutine per connection; a read round's replies leave coalesced in one sendmsg, and a send the socket refuses is finished by the next write turn without pausing the read. Default configuration otherwise.",
"description": "uws WebSocket echo on uio: the RFC 6455 handshake and frame parser run in the connection's own I/O task on uio's edge-triggered event loops, one per CPU, so each message is parsed from the buffer its task read into and echoed from that task with no goroutine per connection; a read round's replies leave coalesced in one sendmsg, and a send the socket refuses is finished by the next write turn without pausing the read. A SO_REUSEPORT listener group puts each upgrade on the loop that runs its connection. uio defaults otherwise.",
"repo": "https://github.com/urpc/uio",
"type": "experimental",
"engine": "uio",
Expand Down
114 changes: 57 additions & 57 deletions site/data/results/uio-ws.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,151 +4,151 @@
"echo-ws-16384": {
"framework": "uio-ws",
"language": "Go",
"rps": 3288042,
"avg_latency": "4.84ms",
"p99_latency": "6.36ms",
"cpu": "6036.8%",
"memory": "169MiB",
"rps": 3578548,
"avg_latency": "4.53ms",
"p99_latency": "48.00ms",
"cpu": "6522.0%",
"memory": "156MiB",
"connections": 16384,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "22.34MB/s",
"bandwidth": "24.29MB/s",
"reconnects": 0,
"status_2xx": 16440214,
"status_2xx": 17892742,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-4096": {
"framework": "uio-ws",
"language": "Go",
"rps": 3452469,
"avg_latency": "1.18ms",
"p99_latency": "1.98ms",
"cpu": "6268.6%",
"memory": "81MiB",
"rps": 3693055,
"avg_latency": "1.10ms",
"p99_latency": "13.20ms",
"cpu": "6521.8%",
"memory": "73MiB",
"connections": 4096,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "23.10MB/s",
"bandwidth": "24.67MB/s",
"reconnects": 0,
"status_2xx": 17262348,
"status_2xx": 18465277,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-512": {
"framework": "uio-ws",
"language": "Go",
"rps": 3638507,
"avg_latency": "140us",
"p99_latency": "292us",
"cpu": "6375.8%",
"memory": "49MiB",
"rps": 3460527,
"avg_latency": "147us",
"p99_latency": "260us",
"cpu": "6561.1%",
"memory": "47MiB",
"connections": 512,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "24.28MB/s",
"bandwidth": "23.10MB/s",
"reconnects": 0,
"status_2xx": 18192535,
"status_2xx": 17302636,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-limited-4096": {
"framework": "uio-ws",
"language": "Go",
"rps": 1022019,
"avg_latency": "178us",
"p99_latency": "1.14ms",
"cpu": "3293.4%",
"memory": "64MiB",
"rps": 2034053,
"avg_latency": "1.33ms",
"p99_latency": "12.00ms",
"cpu": "5632.3%",
"memory": "100MiB",
"connections": 4096,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "19.39MB/s",
"reconnects": 510982,
"status_2xx": 5110095,
"bandwidth": "38.60MB/s",
"reconnects": 1016829,
"status_2xx": 10170265,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-limited-512": {
"framework": "uio-ws",
"language": "Go",
"rps": 1028217,
"avg_latency": "172us",
"p99_latency": "1.13ms",
"cpu": "3417.3%",
"rps": 1869683,
"avg_latency": "181us",
"p99_latency": "776us",
"cpu": "5782.4%",
"memory": "66MiB",
"connections": 512,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "19.51MB/s",
"reconnects": 514174,
"status_2xx": 5141088,
"bandwidth": "35.47MB/s",
"reconnects": 934861,
"status_2xx": 9348417,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-pipeline-16384": {
"framework": "uio-ws",
"language": "Go",
"rps": 44743779,
"avg_latency": "5.70ms",
"p99_latency": "7.82ms",
"cpu": "5942.6%",
"memory": "169MiB",
"rps": 52468675,
"avg_latency": "4.87ms",
"p99_latency": "56.90ms",
"cpu": "6191.0%",
"memory": "163MiB",
"connections": 16384,
"threads": 64,
"duration": "5s",
"pipeline": 16,
"bandwidth": "299.02MB/s",
"bandwidth": "350.56MB/s",
"reconnects": 0,
"status_2xx": 223718897,
"status_2xx": 262343376,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-pipeline-4096": {
"framework": "uio-ws",
"language": "Go",
"rps": 46504867,
"avg_latency": "1.40ms",
"p99_latency": "2.61ms",
"cpu": "6207.1%",
"memory": "81MiB",
"rps": 54415846,
"avg_latency": "1.16ms",
"p99_latency": "17.50ms",
"cpu": "6564.5%",
"memory": "73MiB",
"connections": 4096,
"threads": 64,
"duration": "5s",
"pipeline": 16,
"bandwidth": "310.44MB/s",
"bandwidth": "363.23MB/s",
"reconnects": 0,
"status_2xx": 232524336,
"status_2xx": 272079234,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
},
"echo-ws-pipeline-512": {
"framework": "uio-ws",
"language": "Go",
"rps": 49165507,
"avg_latency": "165us",
"p99_latency": "299us",
"cpu": "6455.1%",
"memory": "49MiB",
"rps": 51867254,
"avg_latency": "157us",
"p99_latency": "269us",
"cpu": "6391.1%",
"memory": "50MiB",
"connections": 512,
"threads": 64,
"duration": "5s",
"pipeline": 16,
"bandwidth": "328.13MB/s",
"bandwidth": "346.14MB/s",
"reconnects": 0,
"status_2xx": 245827535,
"status_2xx": 259336271,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
Expand Down