Comments (8)
Use it like:
srv := tcpx.NewTcpX(nil)
srv.BeforeExit(job1, job2, job3 ...)
srv.ListenAndServe("tcp", ":8080")
Here is part of source code:
func (tcpx TcpX) BeforeExit(f ...func()) {
go func() {
defer func() {
if e := recover(); e != nil {
fmt.Println(fmt.Sprintf("panic from %v", e))
}
}()
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT)
fmt.Println("receive signal:", <-ch)
fmt.Println("prepare to stop server")
for _, handler := range f {
handler()
}
os.Exit(0)
}()
}
It will catch syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT
these signal and do all jobs you design as 'func()'.
Does this fit your requirement?
from tcpx.
I hope the listener and connection normal close, not os.exit(0)
from tcpx.
It'hard.Because there is not a specific pause point for ListenAndServe()
to insert a context
whatever it's about tcp, udp, or kcp.It means you can't run server in another goroutine and control it by the context.
Mayby you can design a middleware and using a value to control server' context Abort
, it will look like:
var access bool
func main()
srv := tcpx.NewTcpX(nil)
srv.AddHandler(1, setAccess)
srv.Use("server-access",Access)
// srv.AddHandler()
srv.ListenAndServe("tcp", ":8080")
}
func Access(c *tcpx.Context){
if !access {
c.Abort()
return
}
}
func setAccess(c *tcpx.Context) {
access = !access
}
But I shall notice you that if you're using srv.OnMessage
instead of AddHandler
, middleware by Use()
will not make sense. If not using srv.OnMessage
, you can just ignore these.
from tcpx.
- close conn maybe use ClientPool:
type ClientPool struct {
Clients map[string]*Context
m *sync.RWMutex
}
func (cp *ClientPool) Close() {
cp.m.Lock()
defer cp.m.Unlock()
for _,c := range cp.Clients{
c.CloseConn()
}
}
- close listener accept maybe like this:
type TcpX struct {
listener *net.TCPListener
pool *ClientPool
...
}
func (this *TcpX) Close() {
if this.pool != nil{
this.pool.Close()
}
if this.listener != nil{
this.listener.Close()
}
}
test example:
listener,err := net.Listen("tcp","0.0.0.0:8888")
if err != nil{
fmt.Println("listen failed, ",err.Error())
}
go func() {
for {
_,err := listener.Accept()
if err != nil{
fmt.Println("accept failed, " + err.Error())
return
}
}
}()
time.Sleep(5 * time.Second)
err = listener.Close()
if err != nil{
fmt.Println("listener close failed, ",err.Error())
}
from tcpx.
I seldom meet this situation. When I want to realize that stoping part of server makes no effects to another part, I ussually consider it in these layers:
- Tear apart tcp server and http server into two progresses.Each process can restart/close as I wish and no effect to another. If there is nessasary interactions, I will start a grpc server in tcp part as grpc server side and http part as grpc client side.
- If http part and tcp part share too many codes and I don't want to use grpc. I will use the same project code to generate two servers, like:
var serverType string
var port string
func main(){
flag.StringVal(&serverType, "server_type", "http,tcp", "go run main.go -server_type tcp")
flag.StringVal(&serverType, "p", ":8080", "go run main.go -p :8080")
flag.Parse()
if strings.Contains(serverType, "tcp") {
go tcpServer(port)
}
if strings.Contains(serverType, "http") {
go httpServer(port)
}
}
go run main.go -server_type tcp -p 8080
go run main.go -server_type http -p 8081
If you insist on this requirement, I can realize one. But I will not design it as you like via close listener
, close pool connection
.
Why?
Because listener
can Close
but cannot Restart
, as long as you make it graceful to stop tcp server, you can no longer graceful restart it.You still have to restart the whole process.
I will design it as I've said,
add a mux handler to stop server access
close all connection
but listener still accepts connection, connection will stop by access handler
or I can ignore step 2, I even don't have to close all connection as long as you set heartbeat-mode on.
Because all server handlers deny requests, heartbeat will also deny , after interval receiving no heartbeat pack, connection auto-close.
from tcpx.
Just shut down the TCP service, simple things don't get complicated, don't grpc, don't http, why can't listen restart?
`type TcpX struct {
listener *net.TCPListener
pool *ClientPool
...
}
func (this *TcpX) Start() (err error) {
this.listener,err = net.ListenTCP("tcp","0.0.0.0:8888")
...
}
func (this *TcpX) Close() {
if this.listener != nil{
this.listener.Close()
this.listener = nil
}
}
func (this *TcpX) Restart() {
this.Close()
this.Start()
}`
Most TCP/HTTP services support shutting down services, such as xtcp, gotcp, beego and so on. Why don't you support it?
from tcpx.
Done.
Example refers to https://github.com/fwhezfwhez/tcpx/tree/master/examples/modules/graceful.
Have fun!
from tcpx.
tks.
from tcpx.
Related Issues (20)
- [feature-asking] Can add connections,throughput,response delay benchmarks ? HOT 1
- [feature-asking] Can you normalize the name of the network package read interface function? HOT 1
- picture repo HOT 3
- [feature-asking]How tcpx works in distribution system?
- /root/go/src/github.com/fwhezfwhez/tcpx/log.go:34: can't read 784 length content block from reader, but read 196 HOT 14
- 有做分布式的计划吗? HOT 2
- [Promotion]Profile usage of anchor middleware
- 心跳具体要怎么配置? HOT 6
- 有时候解析包出错 HOT 10
- [Promotion] Provide url style routing way, help tcpx practice better!
- 当收到错误报文时,会产生fatal error: runtime: out of memory致命错误 HOT 1
- 需要新添加可自动检测指定时间内没发送心跳就下线 HOT 1
- 需要新增一个 可以获取客户端(非极端环境下)断开连接的userid HOT 1
- 需要新增一个 HeartBeatModeDetail 可重写的 HOT 1
- 会自动触发掉线 HOT 1
- [Promotion] Enable tls
- tcp client的例子跑一下就死了 HOT 2
- [enhancement-candidate] Graceful stop, graceFul restart practice bad
- connection pool high-availeble supporting HOT 2
- go get github.com/fwhezfwhez/tcpx go get github.com/fwhezfwhez/tcpx: no matching versions for query "upgrade"
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tcpx.