I think this works for some cases, but it is potentially wasteful (and even leaky) in terms of resource usage.
For example, if ctx is context.Background(), it leaks a goroutine for every connection. It also keeps the additional goroutine around for the entire lifetime of the connection. I'd like to present a more involved, but more robust and precise approach: https://play.golang.org/p/OgsE3erjJTK I have not tested the code on anything real, but I hope it's correct, and that it helps. You might not need the entire machinery, but maybe other readers of this thread do. On Wed, Jul 8, 2020 at 11:45 AM Brian Candler <b.cand...@pobox.com> wrote: > Thank you, that was what I was looking for. I had forgotten about > deadlines, and I didn't realise that you could change a deadline even while > a read was in progress. > > In case it's helpful to anyone, here's a proof-of-concept. It doesn't > work on play.golang.org because of the network communication. > > package main > > import ( > "context" > "fmt" > "io" > "net" > "os" > "time" > ) > > type ConnWithContext struct { > net.Conn > Ctx context.Context > } > > func NewConnWithContext(ctx context.Context, conn net.Conn) > *ConnWithContext { > go func() { > <-ctx.Done() > conn.SetDeadline(time.Now()) > }() > return &ConnWithContext{ > Conn: conn, > Ctx: ctx, > } > } > > func (c *ConnWithContext) Read(b []byte) (n int, err error) { > return c.Conn.Read(b) > } > > func main() { > ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) > defer cancel() > > conn, err := net.Dial("tcp", "smtp.gmail.com:25") > if err != nil { > fmt.Println(err) > return > } > cwc := NewConnWithContext(ctx, conn) > n, err := io.Copy(os.Stdout, cwc) > fmt.Println(n, err) > cwc.Close() > } > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/c7d926b1-7b05-47a0-9eb3-f0e1533b81a6o%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/c7d926b1-7b05-47a0-9eb3-f0e1533b81a6o%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- Andrei Călin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CANnvmN4ycskVCsSxtqDJC%2Bzb8STLnH4EeyWRoqOq14QDwPeG%2Bw%40mail.gmail.com.