mirror of
https://github.com/smallnest/rpcx.git
synced 2026-04-22 15:17:11 +08:00
add io_uring support
This commit is contained in:
@@ -18,11 +18,12 @@ import (
|
||||
type ConnFactoryFn func(c *Client, network, address string) (net.Conn, error)
|
||||
|
||||
var ConnFactories = map[string]ConnFactoryFn{
|
||||
"http": newDirectHTTPConn,
|
||||
"kcp": newDirectKCPConn,
|
||||
"quic": newDirectQuicConn,
|
||||
"unix": newDirectConn,
|
||||
"memu": newMemuConn,
|
||||
"http": newDirectHTTPConn,
|
||||
"kcp": newDirectKCPConn,
|
||||
"quic": newDirectQuicConn,
|
||||
"unix": newDirectConn,
|
||||
"memu": newMemuConn,
|
||||
"iouring": newIOUringConn,
|
||||
}
|
||||
|
||||
// Connect connects the server via specified network.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// experimental
|
||||
func newIOUringConn(c *Client, network, address string) (net.Conn, error) {
|
||||
return newDirectConn(c, "tcp", address)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/smallnest/rpcx/server"
|
||||
)
|
||||
|
||||
func TestXClient_IOUring(t *testing.T) {
|
||||
s := server.NewServer()
|
||||
s.RegisterName("Arith", new(Arith), "")
|
||||
go s.Serve("iouring", "127.0.0.1:8972")
|
||||
defer s.Close()
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
addr := s.Address().String()
|
||||
|
||||
d, err := NewPeer2PeerDiscovery("iouring@"+addr, "desc=a test service")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to NewPeer2PeerDiscovery: %v", err)
|
||||
}
|
||||
|
||||
xclient := NewXClient("Arith", Failtry, RandomSelect, d, DefaultOption)
|
||||
|
||||
defer xclient.Close()
|
||||
|
||||
args := &Args{
|
||||
A: 10,
|
||||
B: 20,
|
||||
}
|
||||
|
||||
reply := &Reply{}
|
||||
err = xclient.Call(context.Background(), "Mul", args, reply)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to call: %v", err)
|
||||
}
|
||||
|
||||
if reply.C != 200 {
|
||||
t.Fatalf("expect 200 but got %d", reply.C)
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ require (
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
@@ -57,6 +58,7 @@ require (
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/reedsolomon v1.11.7 // indirect
|
||||
github.com/kr/text v0.1.0 // indirect
|
||||
github.com/libp2p/go-sockaddr v0.1.1 // indirect
|
||||
github.com/lucas-clemente/quic-go v0.31.1 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.4 // indirect
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.2 // indirect
|
||||
|
||||
@@ -93,6 +93,8 @@ github.com/go-redis/redis_rate/v9 v9.1.2/go.mod h1:oam2de2apSgRG8aJzwJddXbNu91Iy
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 h1:5zELAgnSz0gqmr4Q5DWCoOzNHoeBAxVUXB7LS1eG+sw=
|
||||
github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5/go.mod h1:ermjEDUoT/fS+3Ona5Vd6t6mZkw1eHp99ILO5jGRBkM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
@@ -201,6 +203,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ=
|
||||
github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
|
||||
github.com/lucas-clemente/quic-go v0.28.0/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0=
|
||||
github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4=
|
||||
github.com/lucas-clemente/quic-go v0.31.1/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
|
||||
@@ -486,6 +490,7 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -35,6 +35,10 @@ func SetLogger(logger Logger) {
|
||||
l = logger
|
||||
}
|
||||
|
||||
func GetLogger() Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func SetDummyLogger() {
|
||||
l = &dummyLogger{}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
uringnet "github.com/godzie44/go-uring/net"
|
||||
"github.com/godzie44/go-uring/reactor"
|
||||
"github.com/godzie44/go-uring/uring"
|
||||
"github.com/smallnest/rpcx/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
makeListeners["iouring"] = iouringMakeListener
|
||||
}
|
||||
|
||||
// iouringMakeListener creates a new listener using io_uring.
|
||||
// You can use RegisterMakeListener to register a customized iouring Listener creator.
|
||||
// experimental
|
||||
func iouringMakeListener(s *Server, address string) (ln net.Listener, err error) {
|
||||
n := runtime.GOMAXPROCS(-1)
|
||||
|
||||
var opts []uring.SetupOption
|
||||
opts = append(opts, uring.WithSQPoll(time.Millisecond*100))
|
||||
|
||||
rings, closeRings, err := uring.CreateMany(n, uring.MaxEntries>>3, n, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
netReactor, err := reactor.NewNet(rings, reactor.WithLogger(&uringLogger{log.GetLogger()}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ln, err = uringnet.NewListener(net.ListenConfig{}, address, netReactor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &uringnetListener{Listener: ln, closeRings: closeRings}, nil
|
||||
}
|
||||
|
||||
type uringnetListener struct {
|
||||
net.Listener
|
||||
closeRings uring.Defer
|
||||
}
|
||||
|
||||
func (cl *uringnetListener) Close() error {
|
||||
cl.Listener.Close()
|
||||
cl.closeRings()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type uringLogger struct {
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func (l *uringLogger) Log(keyvals ...interface{}) {
|
||||
l.Logger.Info(keyvals...)
|
||||
}
|
||||
Reference in New Issue
Block a user