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.

Reply via email to