Let's say I have a golang function that goes something like:
conn, _ := ln.Accept()
r := bufio.NewReader(conn)
func waiter(r *bufio.Reader) {
r.ReadString('\n')
}
go waiter(r)
time.Sleep(time.Second)
fmt.Println("hello")
Is there a way for me to cancel the waiter so it's not hung waiting for a string input if it never comes? The issue is the bufio reader is blocking, and I want to have it wait for two seconds on a ticker, and if it doesn't read in any data to the buffer to escape the goroutine.
Conn
interface provides a method SetReadDeadline
to interrupt staled operation at specific time:
for {
// Set a deadline for reading. Read operation will fail if no data
// is received after deadline.
conn.SetReadDeadline(time.Now().Add(timeoutDuration))
// Read tokens delimited by newline
bytes, err := bufReader.ReadBytes('\n')
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s", bytes)
}
http://www.mrleong.net/post/130329994134/go-tcp-connection-listening-and-timeout
EDIT: Context can't do anything with blocking Read function, that is this is not the correct solution for the question. Better to set idle timeout to the connection in this situation.
You can use context
package to control goroutines. Context is mostly used to stop the goroutine in case it is cancelled, timeout, etc. To use it, you must receive one more argument ctx context
, and run select in your goroutine.
Example from Godoc:
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err()) // prints "context deadline exceeded"
}
}
Read more about context use cases in official blog post: https://blog.golang.org/context
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.