最近的事情挺杂的,开发的工作量也就小了很多,只能记录一些零碎的知识点。

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 拍摄的封面图片,虽然截取之后不是那么完美了