I have a long-lived streaming json response that I'm processing in a goroutine as follows. I'm using a quit channel to exit the goroutine periodically. Quitting works great while data's flowing (on the next loop), however, while nothing's being streamed, decoder.Decode holds up execution waiting for the next line of json, which holds up the quit. Suggestions on how to quit gracefully?
quit := make(chan bool)
decoder := json.NewDecoder(response.Body) // response.Body is streaming json
go func() {
for {
select {
case <-quit:
return
default:
decoder.Decode(&myStruct) // this blocks when there's no data
process myStruct...
}
}
}()
... quit <- true // stop execution as needed
You can't interrupt a blocking read. If you want to interrupt reading of the response body, you need to cancel the http request. This will close the connection, causing the blocked io.Reader
to return io.EOF
.
Create a "cancellable" request using the Request.WithContext method, and provide it with a cancellation context.