diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..f97dd8b
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,43 @@
+name: Gain package
+
+on:
+ push:
+ branches:
+ - main
+ - dev
+ paths-ignore:
+ - '**.md'
+ pull_request:
+ branches:
+ - main
+ - dev
+ paths-ignore:
+ - '**.md'
+
+# env:
+ # TEST_PRINT_MAPS_AND_FDS: true
+ # TEST_LOGGER_LEVEL: trace
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Tune GitHub-hosted runner network
+ uses: smorimoto/tune-github-hosted-runner-network@v1
+
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: '1.19.x'
+
+ - name: Install dependencies
+ run: go get .
+
+ - name: Run coverage
+ run: go test -v ./... -timeout 30s -coverprofile=coverage.out -covermode=atomic
+
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v3
diff --git a/README.md b/README.md
index 6a6fb43..af4ba43 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,15 @@
-[![Apache 2.0 License][license-shield]][license-url]
-
+ [![Apache 2.0 License][license-shield]][license-url]
+ [![Go Reference](https://pkg.go.dev/badge/github.com/pawelgaczynski/gain.svg)](https://pkg.go.dev/github.com/pawelgaczynski/gain)
+ [![Go Report Card](https://goreportcard.com/badge/github.com/pawelgaczynski/gain)](https://goreportcard.com/report/github.com/pawelgaczynski/gain)
+
Gain
@@ -55,6 +57,7 @@ Gain is a high-performance networking framework written entirely in Go. It uses
Articles about the project:
* [Medium - Meet Gain - the New Fastest Go TCP Framework](https://medium.com/better-programming/gain-the-new-fastest-go-tcp-framework-40ec111d40e6)
+* [Medium - Writing High-performance TCP Applications Using the Gain Web Framework](https://medium.com/better-programming/an-introduction-to-gain-part-1-writing-high-performance-tcp-application-df5f7253e54a)
@@ -67,7 +70,7 @@ Articles about the project:
### Prerequisites
-Gain requires Go 1.18+
+Gain requires Go 1.19+
@@ -75,7 +78,7 @@ Gain requires Go 1.18+
1. Install the framework
```sh
- go get -u github.com/pawelgaczynski/gain@v0.2.0-alpha
+ go get -u github.com/pawelgaczynski/gain@v0.3.0-alpha
```
(back to top)
diff --git a/common_conn_test.go b/common_conn_test.go
index c935466..b7edaae 100644
--- a/common_conn_test.go
+++ b/common_conn_test.go
@@ -27,7 +27,6 @@ import (
"time"
"github.com/pawelgaczynski/gain"
- "github.com/rs/zerolog"
. "github.com/stretchr/testify/require"
)
@@ -121,7 +120,7 @@ type testConnClient struct {
}
func (c *testConnClient) Dial() {
- conn, err := net.DialTimeout(c.network, fmt.Sprintf("localhost:%d", c.port), time.Millisecond*500)
+ conn, err := net.DialTimeout(c.network, fmt.Sprintf("127.0.0.1:%d", c.port), time.Second)
Nil(c.t, err)
NotNil(c.t, conn)
c.conn = conn
@@ -212,7 +211,7 @@ func newTestConnServer(
) (gain.Server, int) {
t.Helper()
opts := []gain.ConfigOption{
- gain.WithLoggerLevel(zerolog.FatalLevel),
+ gain.WithLoggerLevel(getTestLoggerLevel()),
gain.WithWorkers(4),
gain.WithArchitecture(architecture),
gain.WithAsyncHandler(async),
@@ -224,7 +223,7 @@ func newTestConnServer(
testPort := getTestPort()
go func() {
- err := server.Start(fmt.Sprintf("%s://localhost:%d", network, testPort))
+ err := server.Start(fmt.Sprintf("%s://127.0.0.1:%d", network, testPort))
if err != nil {
log.Panic(err)
}
@@ -252,7 +251,7 @@ func testConnAddress(
t.Helper()
numberOfClients := 10
opts := []gain.ConfigOption{
- gain.WithLoggerLevel(zerolog.FatalLevel),
+ gain.WithLoggerLevel(getTestLoggerLevel()),
gain.WithWorkers(4),
gain.WithArchitecture(architecture),
}
@@ -305,7 +304,7 @@ func testConnAddress(
testPort := getTestPort()
go func() {
- serverErr := server.Start(fmt.Sprintf("%s://localhost:%d", network, testPort))
+ serverErr := server.Start(fmt.Sprintf("%s://127.0.0.1:%d", network, testPort))
if err != nil {
log.Panic(serverErr)
}
diff --git a/common_test.go b/common_test.go
index c4da716..5816819 100644
--- a/common_test.go
+++ b/common_test.go
@@ -30,7 +30,6 @@ import (
"github.com/pawelgaczynski/gain"
gainErrors "github.com/pawelgaczynski/gain/pkg/errors"
gainNet "github.com/pawelgaczynski/gain/pkg/net"
- "github.com/rs/zerolog"
. "github.com/stretchr/testify/require"
)
@@ -192,7 +191,7 @@ var deafultAfterDial = func(t *testing.T, conn net.Conn, repeats, clientIndex in
func dialClient(t *testing.T, protocol string, port int, clientConnChan chan net.Conn) {
t.Helper()
- conn, err := net.DialTimeout(protocol, fmt.Sprintf("localhost:%d", port), time.Second)
+ conn, err := net.DialTimeout(protocol, fmt.Sprintf("127.0.0.1:%d", port), time.Second)
Nil(t, err)
NotNil(t, conn)
clientConnChan <- conn
@@ -202,7 +201,7 @@ func dialClientRW(t *testing.T, protocol string, port int,
afterDial afterDialCallback, repeats, clientIndex int, clientConnChan chan net.Conn,
) {
t.Helper()
- conn, err := net.DialTimeout(protocol, fmt.Sprintf("localhost:%d", port), 2*time.Second)
+ conn, err := net.DialTimeout(protocol, fmt.Sprintf("127.0.0.1:%d", port), 2*time.Second)
Nil(t, err)
NotNil(t, conn)
afterDial(t, conn, repeats, clientIndex)
@@ -233,7 +232,7 @@ func testServer(t *testing.T, testConfig testServerConfig, architecture gain.Ser
log.Panic("network protocol is missing")
}
opts := []gain.ConfigOption{
- gain.WithLoggerLevel(zerolog.FatalLevel),
+ gain.WithLoggerLevel(getTestLoggerLevel()),
gain.WithAsyncHandler(testConfig.asyncHandler),
gain.WithGoroutinePool(testConfig.goroutinePool),
gain.WithCPUAffinity(testConfig.cpuAffinity),
@@ -254,7 +253,7 @@ func testServer(t *testing.T, testConfig testServerConfig, architecture gain.Ser
testPort := getTestPort()
go func() {
- err := server.Start(fmt.Sprintf("%s://localhost:%d", testConfig.protocol, testPort))
+ err := server.Start(fmt.Sprintf("%s://127.0.0.1:%d", testConfig.protocol, testPort))
if err != nil {
log.Panic(err)
}
@@ -400,11 +399,11 @@ func testCloseServer(t *testing.T, network string, architecture gain.ServerArchi
_, err := rand.Read(data)
Nil(t, err)
- clientsGroup.SetDeadline(time.Now().Add(time.Millisecond * 500))
+ clientsGroup.SetDeadline(time.Now().Add(time.Second))
clientsGroup.Write(data)
buffer := make([]byte, 512)
- clientsGroup.SetDeadline(time.Now().Add(time.Millisecond * 500))
+ clientsGroup.SetDeadline(time.Now().Add(time.Second))
clientsGroup.Read(buffer)
clientsGroup.SetDeadline(time.Time{})
@@ -465,7 +464,7 @@ func testCloseConn(t *testing.T, async bool, architecture gain.ServerArchitectur
clientDoneWg.Add(1)
go func(wg *sync.WaitGroup) {
- conn, cErr := net.DialTimeout(gainNet.TCP, fmt.Sprintf("localhost:%d", port), time.Second)
+ conn, cErr := net.DialTimeout(gainNet.TCP, fmt.Sprintf("127.0.0.1:%d", port), time.Second)
Nil(t, cErr)
NotNil(t, conn)
testData := []byte("testdata1234567890")
@@ -497,6 +496,13 @@ func testCloseConn(t *testing.T, async bool, architecture gain.ServerArchitectur
func testLargeRead(t *testing.T, network string, architecture gain.ServerArchitecture) {
t.Helper()
+ if !checkKernelCompatibility(5, 19) {
+ //nolint
+ fmt.Println("Not supported by kernel")
+
+ return
+ }
+
doublePageSize := os.Getpagesize() * 4
data := make([]byte, doublePageSize)
_, err := rand.Read(data)
diff --git a/event_handler_test.go b/event_handler_test.go
index b397e16..842de5b 100644
--- a/event_handler_test.go
+++ b/event_handler_test.go
@@ -16,15 +16,17 @@ package gain_test
import (
"crypto/rand"
+ "errors"
"fmt"
"log"
"net"
"sync"
+ "syscall"
"testing"
"time"
"github.com/pawelgaczynski/gain"
- "github.com/pawelgaczynski/gain/pkg/errors"
+ gainErrors "github.com/pawelgaczynski/gain/pkg/errors"
gainNet "github.com/pawelgaczynski/gain/pkg/net"
. "github.com/stretchr/testify/require"
)
@@ -52,9 +54,9 @@ func testHandlerMethod(
server, port := newTestConnServer(t, network, asyncHandler, architecture, eventHandlerTester)
- conn, err := net.DialTimeout(network, fmt.Sprintf("localhost:%d", port), time.Second*500)
- if err != nil {
- conn, err = net.DialTimeout(network, fmt.Sprintf("localhost:%d", port), time.Second*500)
+ conn, err := net.DialTimeout(network, fmt.Sprintf("127.0.0.1:%d", port), time.Second)
+ if err != nil && !errors.Is(err, syscall.ECONNRESET) {
+ conn, err = net.DialTimeout(network, fmt.Sprintf("127.0.0.1:%d", port), time.Second)
if err != nil {
log.Panic(err)
}
@@ -78,14 +80,14 @@ func testHandlerMethod(
eventHandlerTester.onCloseWg.Wait()
}
+ eventHandlerTester.finished.Store(true)
+
Equal(t, 1, int(eventHandlerTester.onStartCount.Load()))
Equal(t, callCounts[0], int(eventHandlerTester.onAcceptCount.Load()))
Equal(t, callCounts[1], int(eventHandlerTester.onReadCount.Load()))
Equal(t, callCounts[2], int(eventHandlerTester.onWriteCount.Load()))
Equal(t, callCounts[3], int(eventHandlerTester.onCloseCount.Load()))
- eventHandlerTester.finished.Store(true)
-
server.Shutdown()
}
@@ -185,16 +187,31 @@ func TestEventHandlerOnRead(t *testing.T) {
},
}
clientBehavior := func(conn net.Conn) {
+ err := conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 500))
+ if err != nil {
+ log.Panic(err)
+ }
+
n, err := conn.Write(eventHandlerTestData)
Equal(t, eventHandlerTestDataSize, n)
Nil(t, err)
+ buffer := make([]byte, 1024)
+
+ err = conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500))
+ if err != nil {
+ log.Panic(err)
+ }
+ n, err = conn.Read(buffer)
+ Equal(t, n, 0)
+ NotNil(t, err)
+ conn.Close()
}
testCases := createTestCases("JustRead", both, callbacks, clientBehavior, [][]int{
- {1, 1, 0, 0},
- {1, 1, 0, 0},
- {1, 1, 0, 0},
- {1, 1, 0, 0},
+ {1, 1, 0, 1},
+ {1, 1, 0, 1},
+ {1, 1, 0, 1},
+ {1, 1, 0, 1},
{0, 1, 0, 0},
{0, 1, 0, 0},
})
@@ -225,13 +242,14 @@ func TestEventHandlerOnRead(t *testing.T) {
Equal(t, eventHandlerTestDataSize, n)
Nil(t, err)
Equal(t, eventHandlerTestData, buffer[:eventHandlerTestDataSize])
+ conn.Close()
}
testCases = createTestCases("ReadAndWrite", both, callbacks, clientBehavior, [][]int{
- {1, 1, 1, 0},
- {1, 1, 1, 0},
- {1, 1, 1, 0},
- {1, 1, 1, 0},
+ {1, 1, 1, 1},
+ {1, 1, 1, 1},
+ {1, 1, 1, 1},
+ {1, 1, 1, 1},
{0, 1, 1, 0},
{0, 1, 1, 0},
})
@@ -252,7 +270,7 @@ func TestEventHandlerOnRead(t *testing.T) {
onWriteCallback: func(conn gain.Conn, n int) {
buf, err := conn.Next(-1)
Equal(t, 0, len(buf))
- Equal(t, errors.ErrConnectionClosed, err)
+ Equal(t, gainErrors.ErrConnectionClosed, err)
},
}
clientBehavior = func(conn net.Conn) {
@@ -286,10 +304,12 @@ func TestEventHandlerOnAccept(t *testing.T) {
},
}
clientBehavior := func(conn net.Conn) {
- time.Sleep(time.Millisecond * 50)
- n, err := conn.Write(eventHandlerTestData)
- Equal(t, 0, n)
- NotNil(t, err)
+ if conn != nil {
+ time.Sleep(time.Millisecond * 50)
+ n, err := conn.Write(eventHandlerTestData)
+ Equal(t, 0, n)
+ NotNil(t, err)
+ }
}
testCases := createTestCases("JustClose", tcp, callbacks, clientBehavior, [][]int{
@@ -350,13 +370,14 @@ func TestEventHandlerOnAccept(t *testing.T) {
Equal(t, eventHandlerTestDataSize, n)
Nil(t, err)
Equal(t, eventHandlerTestData, buffer[:eventHandlerTestDataSize])
+ conn.Close()
}
testCases = createTestCases("Write", tcp, callbacks, clientBehavior, [][]int{
- {1, 0, 1, 0},
- {1, 0, 1, 0},
- {1, 0, 1, 0},
- {1, 0, 1, 0},
+ {1, 0, 1, 1},
+ {1, 0, 1, 1},
+ {1, 0, 1, 1},
+ {1, 0, 1, 1},
})
testEventHandler(t, testCases)
@@ -428,13 +449,15 @@ func TestEventHandlerOnWrite(t *testing.T) {
Nil(t, err)
Equal(t, eventHandlerTestData, buffer[:eventHandlerTestDataSize])
}
+
+ conn.Close()
}
testCases := createTestCases("AdditionalWrite", tcp, callbacks, clientBehavior, [][]int{
- {1, 1, 2, 0},
- {1, 1, 2, 0},
- {1, 1, 2, 0},
- {1, 1, 2, 0},
+ {1, 1, 2, 1},
+ {1, 1, 2, 1},
+ {1, 1, 2, 1},
+ {1, 1, 2, 1},
})
testEventHandler(t, testCases)
diff --git a/examples/tcp_echo/main.go b/examples/tcp_echo/main.go
index 731cdd7..e1fb0dd 100644
--- a/examples/tcp_echo/main.go
+++ b/examples/tcp_echo/main.go
@@ -92,7 +92,7 @@ func runClients() {
go func() {
time.Sleep(time.Second)
- conn, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", port), time.Second)
+ conn, err := net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%d", port), time.Second)
if err != nil {
log.Panic(err)
}
@@ -124,7 +124,7 @@ func main() {
runClients()
err := gain.ListenAndServe(
- fmt.Sprintf("tcp://localhost:%d", port), &EventHandler{}, gain.WithLoggerLevel(logger.WarnLevel))
+ fmt.Sprintf("tcp://127.0.0.1:%d", port), &EventHandler{}, gain.WithLoggerLevel(logger.WarnLevel))
if err != nil {
log.Panic(err)
}
diff --git a/go.mod b/go.mod
index fee0c19..41de1d8 100644
--- a/go.mod
+++ b/go.mod
@@ -1,9 +1,10 @@
module github.com/pawelgaczynski/gain
-go 1.18
+go 1.19
require (
github.com/alitto/pond v1.7.1
+ github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.26.1
github.com/stretchr/testify v1.8.0
github.com/urfave/cli/v2 v2.23.7
@@ -15,7 +16,6 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.1.0 // indirect
- github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
diff --git a/iouring/accept_test.go b/iouring/accept_test.go
index 251f509..4fa0892 100644
--- a/iouring/accept_test.go
+++ b/iouring/accept_test.go
@@ -68,7 +68,7 @@ func TestAccept(t *testing.T) {
clientConnChan := make(chan net.Conn)
go func() {
- conn, dialErr := net.DialTimeout(gnet.TCP, fmt.Sprintf("localhost:%d", testPort), time.Second)
+ conn, dialErr := net.DialTimeout(gnet.TCP, fmt.Sprintf("127.0.0.1:%d", testPort), time.Second)
Nil(t, dialErr)
clientConnChan <- conn
}()
diff --git a/iouring/common_test.go b/iouring/common_test.go
index 95d556c..0ab40dd 100644
--- a/iouring/common_test.go
+++ b/iouring/common_test.go
@@ -14,7 +14,9 @@
package iouring_test
-import "sync/atomic"
+import (
+ "sync/atomic"
+)
var port int32 = 8000
diff --git a/iouring/msg_ring_test.go b/iouring/msg_ring_test.go
index a5a1771..f8d1853 100644
--- a/iouring/msg_ring_test.go
+++ b/iouring/msg_ring_test.go
@@ -15,6 +15,8 @@
package iouring_test
import (
+ "fmt"
+ "syscall"
"testing"
"github.com/pawelgaczynski/gain/iouring"
@@ -44,6 +46,19 @@ func TestMsgRingItself(t *testing.T) {
numberOfCQEsSubmitted, err := ring.Submit()
Nil(t, err)
+
+ if numberOfCQEsSubmitted == 1 {
+ cqe, cqeErr := ring.WaitCQE()
+ Nil(t, cqeErr)
+
+ if cqe.Res() == -int32(syscall.EINVAL) || cqe.Res() == -int32(syscall.EOPNOTSUPP) {
+ //nolint
+ fmt.Println("Skipping test because of no msg support")
+
+ return
+ }
+ }
+
Equal(t, uint(3), numberOfCQEsSubmitted)
cqes := make([]*iouring.CompletionQueueEvent, 128)
@@ -103,6 +118,19 @@ func TestMsgRing(t *testing.T) {
cqeNr, err := senderRing.Submit()
Nil(t, err)
+
+ if cqeNr == 1 {
+ cqe, cqeErr := senderRing.WaitCQE()
+ Nil(t, cqeErr)
+
+ if cqe.Res() == -int32(syscall.EINVAL) || cqe.Res() == -int32(syscall.EOPNOTSUPP) {
+ //nolint
+ fmt.Println("Skipping test because of no msg support")
+
+ return
+ }
+ }
+
Equal(t, uint(3), cqeNr)
cqes := make([]*iouring.CompletionQueueEvent, 128)
diff --git a/iouring/tcp_recv_send_test.go b/iouring/tcp_recv_send_test.go
index d572365..768d055 100644
--- a/iouring/tcp_recv_send_test.go
+++ b/iouring/tcp_recv_send_test.go
@@ -136,7 +136,7 @@ func TestTCPRecvSend(t *testing.T) {
clientConnChan := make(chan net.Conn)
go func() {
- conn, cErr := net.DialTimeout(gnet.TCP, fmt.Sprintf("localhost:%d", testPort), time.Second)
+ conn, cErr := net.DialTimeout(gnet.TCP, fmt.Sprintf("127.0.0.1:%d", testPort), time.Second)
Nil(t, cErr)
NotNil(t, conn)
bytesWritten, cErr := conn.Write([]byte("testdata1234567890"))
diff --git a/iouring/udp_recv_send_test.go b/iouring/udp_recv_send_test.go
index 1c78a3e..f237c89 100644
--- a/iouring/udp_recv_send_test.go
+++ b/iouring/udp_recv_send_test.go
@@ -153,7 +153,7 @@ func TestUDPRecvSend(t *testing.T) {
clientConnChan := make(chan net.Conn)
go func() {
- conn, cErr := net.DialTimeout("udp", fmt.Sprintf("localhost:%d", testPort), time.Second)
+ conn, cErr := net.DialTimeout("udp", fmt.Sprintf("127.0.0.1:%d", testPort), time.Second)
Nil(t, cErr)
NotNil(t, conn)
bytesWritten, cErr := conn.Write([]byte("testdata1234567890"))
diff --git a/pkg/buffer/magicring/ringbuffer_iouring_test.go b/pkg/buffer/magicring/ringbuffer_iouring_test.go
index aa00040..e6d5a1b 100644
--- a/pkg/buffer/magicring/ringbuffer_iouring_test.go
+++ b/pkg/buffer/magicring/ringbuffer_iouring_test.go
@@ -200,7 +200,7 @@ func TestMagicRingRecvSend(t *testing.T) {
clientConnChan := make(chan net.Conn)
go func() {
- conn, cErr := net.DialTimeout(gainNet.TCP, fmt.Sprintf("localhost:%d", 9876), time.Second)
+ conn, cErr := net.DialTimeout(gainNet.TCP, fmt.Sprintf("127.0.0.1:%d", 9876), time.Second)
Nil(t, cErr)
NotNil(t, conn)
diff --git a/pkg/pool/virtualmem/virtualmem.go b/pkg/pool/virtualmem/virtualmem.go
index 36c09d0..06e3e2e 100644
--- a/pkg/pool/virtualmem/virtualmem.go
+++ b/pkg/pool/virtualmem/virtualmem.go
@@ -96,6 +96,8 @@ func allocateBuffer(size int) []byte {
log.Panic(fmt.Errorf("second internal mmap failed: %w", err))
}
+ syscall.Close(fileDescriptor)
+
sliceHeader := reflect.SliceHeader{
Data: vaddr,
Len: doubleSize(size),
diff --git a/pkg/pool/virtualmem/virtualmem_test.go b/pkg/pool/virtualmem/virtualmem_test.go
index 65554ac..56d783a 100644
--- a/pkg/pool/virtualmem/virtualmem_test.go
+++ b/pkg/pool/virtualmem/virtualmem_test.go
@@ -103,16 +103,16 @@ func BenchmarkVMMemfd(b *testing.B) {
}
}
-const printMapsAndFds = false
+var printMapsAndFds = os.Getenv("TEST_PRINT_MAPS_AND_FDS") == "true"
-var printCmd = func(cmd string) {
+var printCmd = func(label, cmd string) {
out, err := exec.Command("bash", "-c", cmd).Output()
if err != nil {
log.Panic(err)
}
if printMapsAndFds {
- fmt.Println(string(out)) //nolint:forbidigo
+ fmt.Printf("%s: %s\n", label, string(out)) //nolint:forbidigo
}
}
@@ -123,14 +123,17 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
countCmd := fmt.Sprintf("cat /proc/%d/maps | wc -l", pid)
fdCmd := fmt.Sprintf("ls -l /proc/%d/fd | wc -l", pid)
+ printCmd("ulimit -a", "ulimit -a")
+ printCmd("max map count", "sysctl vm.max_map_count")
+
printList := func() {
- printCmd(listCmd)
+ printCmd("list of proc maps", listCmd)
}
printCount := func() {
- printCmd(countCmd)
+ printCmd("count of proc maps", countCmd)
}
printFds := func() {
- printCmd(fdCmd)
+ printCmd("count of proc fds", fdCmd)
}
var (
@@ -149,6 +152,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 100; i++ {
data = allocateBuffer(pagesize)
@@ -158,6 +162,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 1000; i++ {
data = allocateBuffer(pagesize)
@@ -167,6 +172,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -176,6 +182,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -185,6 +192,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -194,6 +202,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -203,6 +212,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -212,6 +222,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -221,6 +232,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -230,6 +242,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -239,6 +252,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 10000; i++ {
data = allocateBuffer(pagesize)
@@ -248,6 +262,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 30000; i++ {
data = allocateBuffer(pagesize)
@@ -257,6 +272,7 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
+ printFds()
for i := 0; i < 60000; i++ {
data = allocateBuffer(pagesize)
@@ -266,6 +282,6 @@ func TestMemfdMMapAndUnmap(_ *testing.T) {
}
printCount()
-
+ printFds()
printList()
}
diff --git a/shard_worker.go b/shard_worker.go
index bd52506..b8f0d89 100644
--- a/shard_worker.go
+++ b/shard_worker.go
@@ -151,8 +151,6 @@ func (w *shardWorker) handleConn(conn *connection, cqe *iouring.CompletionQueueE
w.logDebug().Int("fd", conn.fd).Int32("count", cqe.Res()).Msg("Bytes writed")
conn.setUserSpace()
w.eventHandler.OnWrite(conn, n)
- // conn.setUserSpace()
- // w.eventHandler.OnWrite(conn)
}
default:
diff --git a/util_test.go b/util_test.go
index 807def7..122dcc6 100644
--- a/util_test.go
+++ b/util_test.go
@@ -16,12 +16,82 @@ package gain_test
import (
"net"
+ "os"
"reflect"
+ "strconv"
+ "strings"
"sync/atomic"
+ "syscall"
"github.com/pawelgaczynski/gain"
+ "github.com/rs/zerolog"
)
+var testLoggerLevel = os.Getenv("TEST_LOGGER_LEVEL")
+
+func getTestLoggerLevel() zerolog.Level {
+ if testLoggerLevel == "" {
+ return zerolog.FatalLevel
+ }
+
+ loggerLevel, err := zerolog.ParseLevel(testLoggerLevel)
+ if err != nil {
+ return zerolog.FatalLevel
+ }
+
+ return loggerLevel
+}
+
+func int8ToStr(arr []int8) string {
+ buffer := make([]byte, 0, len(arr))
+
+ for _, v := range arr {
+ if v == 0x00 {
+ break
+ }
+
+ buffer = append(buffer, byte(v))
+ }
+
+ return string(buffer)
+}
+
+func checkKernelCompatibility(expectedKernelVersion, expectedMajorVersion int) bool {
+ var uname syscall.Utsname
+
+ err := syscall.Uname(&uname)
+ if err != nil {
+ return false
+ }
+
+ kernelString := int8ToStr(uname.Release[:])
+
+ kernelParts := strings.Split(kernelString, ".")
+ if len(kernelParts) < 2 {
+ return false
+ }
+
+ kernelVersion, err := strconv.Atoi(kernelParts[0])
+ if err != nil {
+ return false
+ }
+
+ majorVersion, err := strconv.Atoi(kernelParts[1])
+ if err != nil {
+ return false
+ }
+
+ if expectedKernelVersion < kernelVersion {
+ return true
+ }
+
+ if expectedMajorVersion < majorVersion {
+ return true
+ }
+
+ return false
+}
+
var port int32 = 9000
func getTestPort() int {