最近的事情挺杂的,开发的工作量也就小了很多,只能记录一些零碎的知识点。
TCPadd tcp/udp proxy feature
io.EOFconn.Close()use of closed network connectionclosed
然而博民提出质疑:
closedclosed
SetReadDeadlineSetWriteDeadlineclosed
老实话,刚开始我确实是如此想的。
但是随之而来的问题是,如果合理的设置读写的超时时间呢?设置时间长了,socket资源无法被清理,造成资源占用浪费;设置时间短了,在goroutine数量较多的场景下,又会造成性能负担。
那么Golang官方有没有办法给socket连接设置stopped标志量的API呢?在GitHub上搜寻良久,有相似想法的issue很多,但是官方的态度都是坚决拒绝(例:proposal: io: add Context parameter to Reader, etc.)。此路不通,我们得想个别的辙了。
万幸,看到一个很巧妙的解决方案,代码如下所示:
type ReadDeadliner interface {
SetReadDeadline(t time.Time) error
}
func SetReadDeadlineOnCancel(ctx context.Context, d ReadDeadliner) {
go func() {
<-ctx.Done()
d.SetReadDeadline(time.Now())
}()
}
func handleConnection(ctx context.Context, conn net.Conn) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
SetReadDeadlineOnCancel(ctx, conn)
// rest of code goes here, skeleton only shown
for {
n, err := conn.Read(buf) // blocking here waiting for a message
if err != nil {
... see below
}
...
conn.Write(...)
}
}
SetReadDeadlineOnCancelSetReadDeadline
挺好的,Google的mtail项目也是这样处理的(Commit: Simplify pipestream by correctly interrupting a read on context cancel)。
那么我的处理逻辑也相应的修改为(列举一个场景):
closedconn.SetReadDeadline(time.Now())closed
closedconn.SetReadDeadline(time.Now())closedboolchan struct{}
readclosed chanread
muduo
add tcp/udp proxy feature
感谢来自于Pexels 上的 Lisa 拍摄的封面图片,虽然截取之后不是那么完美了