Hi,
I wanted to inquire what the best way is to propagate cancel down to my module.
For context (no pun intended), I am working on a plugin/module that uses SSE. I think my SSE handler currently blocks the shutdown procedure of the Caddy process, and I’d like to clean it up before I release it. So far, I tried to work around it with another channel to make it respond to stop, but it feels dirty.
func (cs *CaddyScope) serveAPIStream(w http.ResponseWriter, r *http.Request) {
w.Header().Set(“Content-Type”, “text/event-stream”)
w.Header().Set(“Cache-Control”, “no-cache”)
w.Header().Set(“X-Accel-Buffering”, “no”)
rc := http.NewResponseController(w)
writeAndFlush := func(data []byte) error {
if _, err := fmt.Fprintf(w, "event: stats\ndata: %s\n\n", data); err != nil {
return err
}
return rc.Flush()
}
if data := cs.snap.get(); data != nil {
if err := writeAndFlush(data); err != nil {
return
}
}
ticker := time.NewTicker(time.Duration(cs.Refresh))
defer ticker.Stop()
for {
select {
case <-r.Context().Done():
return
case <-cs.cancelCtx.Done():
return
case <-ticker.C:
data := cs.snap.get()
if data == nil {
continue
}
if err := writeAndFlush(data); err != nil {
return
}
}
}
}