Fix: Prevent timer goroutine leaks with non-blocking channel operations#35
Merged
zishang520 merged 1 commit intozishang520:mainfrom Aug 17, 2025
Merged
Conversation
- Use non-blocking select in Timer.Stop() to avoid goroutine leak when no reader is present - Add defer cleanup in timer functions to ensure channels are properly drained - Fixes potential goroutine accumulation in long-running applications This resolves issues where timer goroutines could leak when: 1. Timer.Stop() is called but no goroutine is reading from stopCh 2. Timer functions exit without properly draining the stop channel The fix ensures robust cleanup without blocking operations.
zishang520
added a commit
to zishang520/socket.io
that referenced
this pull request
Aug 22, 2025
Upstream: zishang520/engine.io#35 Commit: 1f1931eab8eee06c32d66a343dcd1cb480417dad Changes: - Moved timer logic from utils/timer.go → pkg/utils/timer.go - Adjusted package imports and directory structure
zishang520
added a commit
to zishang520/socket.io
that referenced
this pull request
Aug 22, 2025
Upstream: zishang520/engine.io#35 Commit: zishang520/engine.io@1f1931e Changes: - Moved timer logic from utils/timer.go → pkg/utils/timer.go - Adjusted package imports and directory structure
zishang520
added a commit
to zishang520/socket.io
that referenced
this pull request
Aug 22, 2025
Upstream: zishang520/engine.io#35 Commit: zishang520/engine.io@1f1931e Changes: - Moved timer logic from utils/timer.go → pkg/utils/timer.go - Adjusted package imports and directory structure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🐛 Problem Description
The current timer implementation in
utils/timer.gohas potential goroutine leaks that can accumulate in long-running applications:Timer.Stop()uses a blocking channel send (t.stopCh <- struct{}{}) which can leak goroutines if no reader is present🔧 Solution
This PR implements robust goroutine cleanup with non-blocking channel operations:
Key Changes
Non-blocking Channel Send in
Timer.Stop():Defer Channel Cleanup in Timer Functions: Added proper channel draining in defer blocks
🧪 Testing
These fixes have been tested extensively:
📊 Impact
🚀 Benefits
📝 Files Changed
utils/timer.go: Enhanced timer cleanup logic with non-blocking operations🔗 Related Issues
This fix addresses goroutine leaks commonly seen in:
Tested with: Go 1.24.1, production workloads, extensive smoke testing
Backward Compatible: ✅ Yes
Breaking Changes: ❌ None