Skip to content

Conversation

@Nepomuk5665
Copy link
Contributor

Summary

  • Fix resource leak caused by defer cancel() inside a for loop
  • The cancel functions would accumulate during the loop and only be called when the function returns
  • Extract HTTP request logic to a separate checkLink() method where defer properly releases resources

Bug Description

In RuleLinkCheck.Check(), a context with timeout was created inside a for loop for each annotation being checked:

for _, ann := range entry.Rule.AlertingRule.Annotations.Items {
    // ...
    rctx, cancel := context.WithTimeout(ctx, c.timeout)
    defer cancel()  // BUG: only called when Check() returns, not at end of iteration
    // ...
}

When checking multiple link annotations, the cancel functions would stack up and only be called when Check() returns, not at the end of each loop iteration. This causes:

  1. Context resources to leak during the loop
  2. Potential goroutine leaks from uncanceled contexts
  3. Memory pressure from accumulated cancel functions

Fix

Extract the HTTP request logic into a separate checkLink() method. The defer cancel() in this new method correctly releases resources when each individual link check completes.

Testing

All existing tests pass:

=== RUN   TestRuleLinkCheck
--- PASS: TestRuleLinkCheck (0.01s)

The defer cancel() inside the for loop in Check() would only run when
the function returns, not at the end of each loop iteration. This caused
context cancellation functions to accumulate during the loop, leading to
resource leaks when checking multiple link annotations.

Fix by extracting HTTP request logic to a separate checkLink() method
where defer cancel() properly releases resources at the end of each call.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant