Shutdown gracefully shuts down the stream, sending any supplementary events downstream if required. ONLY call this once all events have been submitted.
(shutdownCtx context.Context)
| 175 | // Shutdown gracefully shuts down the stream, sending any supplementary events downstream if required. |
| 176 | // ONLY call this once all events have been submitted. |
| 177 | func (s *EventStream) Shutdown(shutdownCtx context.Context) error { |
| 178 | s.shutdownOnce.Do(func() { |
| 179 | s.logger.Debug(shutdownCtx, "shutdown initiated", slog.F("outstanding_events", len(s.eventsCh))) |
| 180 | |
| 181 | // Now it is safe to close the events channel; the Start() loop will exit |
| 182 | // after draining remaining events and receivers will stop ranging. |
| 183 | close(s.eventsCh) |
| 184 | }) |
| 185 | |
| 186 | var err error |
| 187 | select { |
| 188 | case <-shutdownCtx.Done(): |
| 189 | // If shutdownCtx completes, shutdown likely exceeded its timeout. |
| 190 | err = xerrors.Errorf("shutdown ended prematurely with %d outstanding events: %w", len(s.eventsCh), shutdownCtx.Err()) |
| 191 | case <-s.ctx.Done(): |
| 192 | err = xerrors.Errorf("shutdown ended prematurely with %d outstanding events: %w", len(s.eventsCh), s.ctx.Err()) |
| 193 | case <-s.doneCh: |
| 194 | return nil |
| 195 | } |
| 196 | |
| 197 | // Even if the context is canceled, we need to wait for Start() to complete. |
| 198 | <-s.doneCh |
| 199 | return err |
| 200 | } |
| 201 | |
| 202 | // IsStreaming checks if the stream has been initiated, or |
| 203 | // when events are buffered which - when processed - will initiate the stream. |
no outgoing calls
no test coverage detected