GithubHelp home page GithubHelp logo

softwarekang / knetty Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 2.0 1.6 MB

Knetty is a network communication framework written in Go based on the event-driven architecture.

License: Apache License 2.0

Go 98.25% Makefile 1.75%
epoll-socket golang kqueue network tcp

knetty's People

Contributors

chever-john avatar softwarekang avatar sunbinnnnn avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

knetty's Issues

Feature Request: Add Network Monitoring framework

Background:
Suppose that we could need to monitor whole net connection and tracing for upper application if meet packet loss, high latency, etc..

How to do:

To support monitor connection and do package tracing if can use some package tracing\monitoring technology like epbf\pt if needed.

feat:ringbuffer 缓存设计使用内存池优化,提高内存复用,避免协程饥饿读写缓存。

Description

  • 现状

    1. 目前每个connection 包含一个ringbuffer,固定大小为64kb。应用层处理多慢,会导致缓冲区很快full,此时会返回充实错误(EGAGIN),epollwait会出现无效的readable func 调用。
    2. 每个connection 的ringbuffer在使用完之后会被GC掉,每次使用会重新申请。
  • 期望

    1. ringbuffer实现线程安全的grow增长,避免epoll进行无效的readable func 调用。
    2. 实现内存池,每个connection可以从内存池获取ringbuffer进行复用

bug: Graceful shutdown of client and server failed

Issue description

Graceful shutdown of client and server failed

Environment

  • go version:v1.18
  • os: all

Minimal test code / Steps to reproduce

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/Softwarekang/knetty"
	"github.com/Softwarekang/knetty/session"
)

func main() {
	// setting optional options for the server
	options := []knetty.ServerOption{
		knetty.WithServiceNewSessionCallBackFunc(newSessionCallBackFn),
	}

	// creating a new server with network settings such as tcp/upd, address such as 127.0.0.1:8000, and optional options
	server := knetty.NewServer("tcp", "127.0.0.1:8000", options...)
	// Initializing the server in a goroutine so that
	// it won't block the graceful shutdown handling below
	go func() {
		if err := server.Server(); err != nil && errors.Is(err, http.ErrServerClosed) {
			log.Printf("run server: %s\n", err)
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with
	quit := make(chan os.Signal)
	// kill (no param) default send syscall.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("shutting down server...")

	// The context is used to inform the server it has 5 seconds to finish
	// the request it is currently handling
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("server starting shutdown:", err)
	}

	log.Println("server exiting")
}

// set the necessary parameters for the session to run.
func newSessionCallBackFn(s session.Session) error {
	s.SetCodec(&codec{})
	s.SetEventListener(&helloWorldListener{})
	s.SetReadTimeout(1 * time.Second)
	s.SetWriteTimeout(1 * time.Second)
	return nil
}

type helloWorldListener struct {
}

func (e *helloWorldListener) OnMessage(s session.Session, pkg interface{}) {
	data := pkg.(string)
	fmt.Printf("server got data:%s\n", data)
}

func (e *helloWorldListener) OnConnect(s session.Session) {
	fmt.Printf("local:%s get a remote:%s connection\n", s.LocalAddr(), s.RemoteAddr())
}

func (e *helloWorldListener) OnClose(s session.Session) {
	fmt.Printf("server session: %s closed\n", s.Info())
}

func (e *helloWorldListener) OnError(s session.Session, err error) {
	fmt.Printf("session: %s got err :%v\n", s.Info(), err)
}

type codec struct {
}

func (c codec) Encode(pkg interface{}) ([]byte, error) {
	if pkg == nil {
		return nil, errors.New("pkg is illegal")
	}
	data, ok := pkg.(string)
	if !ok {
		return nil, errors.New("pkg type must be string")
	}

	if len(data) != 5 || data != "hello" {
		return nil, errors.New("pkg string must be \"hello\"")
	}

	return []byte(data), nil
}

func (c codec) Decode(bytes []byte) (interface{}, int, error) {
	if bytes == nil {
		return nil, 0, errors.New("bytes is nil")
	}

	if len(bytes) < 5 {
		return nil, 0, nil
	}

	data := string(bytes)
	if len(bytes) > 5 {
		data = data[0:5]
	}
	if data != "hello" {
		return nil, 0, errors.New("data is not 'hello'")
	}
	return data, len(data), nil
}

Actual result

.

Error log

.

Expected result

.

Feature Request: Add a private proto `knp` for Knetty

Background:
Many of networking library support private net proto, private proto can be secure and can support delicate flow control.

How to do:
Extened basic TCP with some flow control and secure encryt, first version just for demo and add some example application to use it.

knet session api

Knet needs a session mechanism based on connections to provide apis for users to use. Similar to netty mechanism

[Feature Request]: Implementing a non-blocking read function using chan in place of a for loop.

Now:

Currently, the timeout read function for a TCP connection uses a for loop to implement a check for data being readable.

for {
		if !t.isActive() {
			return 0, merr.ConnClosedErr
		}
		// todo: Using a backoff mechanism to optimize the read function
		if t.inputBuffer.Len() == 0 {
			time.Sleep(1 * time.Second)
			continue
		}

		return t.inputBuffer.Read(p)
	}

Reasons for optimization:

1.In the case where there is no data readable for a long time, the for loop generates a large amount of unnecessary CPU consumption.
2.Reducing CPU consumption through mechanisms such as back off may result in higher data processing latency.

Suggestion:

By using chan to block the goroutine and waking up the goroutine when data is readable, the CPU consumption can be reduced.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.