Improve mutation channel robustness
- Add event type constants (MutationCreate, MutationUpdate, MutationDelete, MutationComment) - Make buffer size configurable via BEADS_MUTATION_BUFFER (default 512, up from 100) - Add defensive closed-channel handling in event loop consumer - Add 1s dropped-events ticker (down from 60s) for faster recovery - Verify mutationChan is never closed (prevents panic) Oracle review findings addressed: - Eliminates panic risk from send-on-closed-channel - Reduces worst-case recovery latency from 60s to 1s - Increases buffer capacity for better burst handling - Type-safe event constants prevent string typos Related: bd-36320a04, bd-1f4086c5
This commit is contained in:
@@ -60,7 +60,12 @@ func runEventDrivenLoop(
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event := <-mutationChan:
|
||||
case event, ok := <-mutationChan:
|
||||
if !ok {
|
||||
// Channel closed (should never happen, but handle defensively)
|
||||
log.log("Mutation channel closed; exiting listener")
|
||||
return
|
||||
}
|
||||
log.log("Mutation detected: %s %s", event.Type, event.IssueID)
|
||||
exportDebouncer.Trigger()
|
||||
|
||||
@@ -70,23 +75,28 @@ func runEventDrivenLoop(
|
||||
}
|
||||
}()
|
||||
|
||||
// Optional: Periodic health check and dropped events safety net
|
||||
// Periodic health check
|
||||
healthTicker := time.NewTicker(60 * time.Second)
|
||||
defer healthTicker.Stop()
|
||||
|
||||
// Dropped events safety net (faster recovery than health check)
|
||||
droppedEventsTicker := time.NewTicker(1 * time.Second)
|
||||
defer droppedEventsTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-healthTicker.C:
|
||||
// Periodic health validation (not sync)
|
||||
checkDaemonHealth(ctx, store, log)
|
||||
|
||||
// Safety net: check for dropped mutation events
|
||||
case <-droppedEventsTicker.C:
|
||||
// Check for dropped mutation events every second
|
||||
dropped := server.ResetDroppedEventsCount()
|
||||
if dropped > 0 {
|
||||
log.log("WARNING: %d mutation events were dropped, triggering export", dropped)
|
||||
exportDebouncer.Trigger()
|
||||
}
|
||||
|
||||
case <-healthTicker.C:
|
||||
// Periodic health validation (not sync)
|
||||
checkDaemonHealth(ctx, store, log)
|
||||
|
||||
case sig := <-sigChan:
|
||||
if isReloadSignal(sig) {
|
||||
log.log("Received reload signal, ignoring")
|
||||
|
||||
Reference in New Issue
Block a user