Skip to content

Instantly share code, notes, and snippets.

@kostanovych
Created October 17, 2018 22:40
Show Gist options
  • Save kostanovych/38e4ec28a57d3645a80be88cbffc5b84 to your computer and use it in GitHub Desktop.
Save kostanovych/38e4ec28a57d3645a80be88cbffc5b84 to your computer and use it in GitHub Desktop.
Golang long polling example with request cancellation
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func longOperation(ctx context.Context, ch chan<- string) {
// Simulate long operation.
// Change it to more than 10 seconds to get server timeout.
select {
case <-time.After(time.Second * 3):
ch <- "Successful result."
case <-ctx.Done():
close(ch)
}
}
func handler(w http.ResponseWriter, _ *http.Request) {
notifier, ok := w.(http.CloseNotifier)
if !ok {
panic("Expected http.ResponseWriter to be an http.CloseNotifier")
}
ctx, cancel := context.WithCancel(context.Background())
ch := make(chan string)
go longOperation(ctx, ch)
select {
case result := <-ch:
fmt.Fprint(w, result)
cancel()
return
case <-time.After(time.Second * 10):
fmt.Fprint(w, "Server is busy.")
case <-notifier.CloseNotify():
fmt.Println("Client has disconnected.")
}
cancel()
<-ch
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe("localhost:8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment