Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/kqueue support et #430

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

byene0923
Copy link
Collaborator

  1. add MaxConnReadTimesPerEventLoop support in Kqueue
  2. add ET support for Kqueue

by the way, this is the wip version, I wrote the example in the bsd machine, but I have no linux machine now, i will test in linux version latter,

@byene0923 byene0923 requested a review from lesismal May 9, 2024 09:34
@byene0923
Copy link
Collaborator Author

package main

import (
	"context"
	"fmt"
	"github.com/lesismal/nbio"
	"github.com/lesismal/nbio/logging"
	"time"
)

func LTServer() {
	engine := nbio.NewEngine(nbio.Config{
		Network:                      "tcp",
		Addrs:                        []string{":8899"},
		ReadBufferSize:               2,
		MaxConnReadTimesPerEventLoop: 1,
		MaxWriteBufferSize:           2,
	})

	engine.OnData(func(c *nbio.Conn, data []byte) {
		fmt.Printf("【LT】read data len: %d, value: %s\n", len(data), string(data))
	})
	err := engine.Start()
	if err != nil {
		fmt.Printf("nbio.start failed: %v\n", err)
		return
	}
	defer engine.Stop()
	time.Sleep(3 * time.Second)
	go Client("localhost:8899", "hello")

	<-make(chan int)
}

// ETServer In ETMod
func ETServer() {
	engine := nbio.NewEngine(nbio.Config{
		Network:                      "tcp",
		Addrs:                        []string{":8888"},
		ReadBufferSize:               2,
		MaxConnReadTimesPerEventLoop: 1,
		MaxWriteBufferSize:           2,
		EpollMod:                     nbio.EPOLLET,
	})

	engine.OnData(func(c *nbio.Conn, data []byte) {
		fmt.Printf("【ET】read data len: %d, value: %s\n", len(data), string(data))
	})
	err := engine.Start()
	if err != nil {
		fmt.Printf("nbio.start failed: %v\n", err)
		return
	}
	defer engine.Stop()
	time.Sleep(3 * time.Second)
	go Client("localhost:8888", "world")

	<-make(chan int)
}

func Client(addr string, data string) {
	ctx, _ := context.WithTimeout(context.Background(), 60*time.Second)
	engine := nbio.NewEngine(nbio.Config{})
	done := make(chan int)

	err := engine.Start()
	if err != nil {
		fmt.Printf("start failed: %v\n", err)
	}
	defer engine.Stop()

	c, err := nbio.Dial("tcp", addr)
	if err != nil {
		panic(err)
	}
	engine.AddConn(c)
	time.Sleep(2 * time.Second)
	c.Write([]byte(data))

	select {
	case <-ctx.Done():
		logging.Error("timeout")
	case <-done:
		logging.Info("success")
	}
}

// The difference of ET and LT
// In LT mode, Kernel will register epitem to wq again after trigger event, but In ET mode,  Kernel will not register
// epitem to wq

// How nbio handle
// when socket data first come, io poller for per conn will only register Read Event(linux call EPOLLIN, bsd call EVFILT_READ)
// When Read event come
// In LT mode, nbio will read MaxConnReadTimesPerEventLoop * ReadBufferSize size。left data will be read in next Read Event
// In ET mode, nbio will change MaxConnReadTimesPerEventLoop to (1<<31 - 1), this indicates nbio will read all the data

// When Write event come and Kernel can't read all the data
// In LT / ET, nbio will both register the Write event(linux call EPOLLOUT, bsd call EVFILT_WRITE)。and when next Write event arrive
// nbio will call flush() to write left data and finally reset the Read Event
func main() {
	logging.SetLevel(logging.LevelDebug)
	fmt.Println("start to handle LT server")
	go LTServer()
	time.Sleep(10 * time.Second)
	fmt.Println("start to handle ET server")
	go ETServer()
	<-make(chan int)
}

this example indicates how nbio will handle ET and LT
In ET mode, output

2024/05/10 13:29:06.392 [DBG] NBIO[NB][POLLER_0] trigger event, filter: -1, mod: 1
【ET】read data len: 2, value: wo
【ET】read data len: 2, value: rl
【ET】read data len: 1, value: d

In LT mode, output

2024/05/10 13:28:56.396 [DBG] NBIO[NB][POLLER_1] trigger event, filter: -1, mod: 0
【LT】read data len: 2, value: he
2024/05/10 13:28:56.396 [DBG] NBIO[NB][POLLER_1] trigger event, filter: -1, mod: 0
【LT】read data len: 2, value: ll
2024/05/10 13:28:56.396 [DBG] NBIO[NB][POLLER_1] trigger event, filter: -1, mod: 0
【LT】read data len: 1, value: o

@byene0923 byene0923 changed the title (WIP) Feat/kqueue support et Feat/kqueue support et May 10, 2024
@byene0923
Copy link
Collaborator Author

@lesismal is there any case that i ignore?

@lesismal
Copy link
Owner

I will run some test

@lesismal
Copy link
Owner

please add ./idea to gitignore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants