- Update KNOWN_ISSUES.md to reflect the mitigation of goroutine leaks and reduced memory growth, detailing the current status and residual behaviors. - Enhance the state worker lifecycle in manager.go to ensure proper command processing and cleanup. - Implement a safe three-step shutdown sequence in trace.go for the Release function, improving resource management and preventing premature exits. - Adjust memory leak test thresholds in KNOWN_ISSUES.md to accommodate improved performance metrics.
102 lines
3.5 KiB
Markdown
102 lines
3.5 KiB
Markdown
# Trace Module - Known Issues
|
|
|
|
This document tracks known issues in the Trace module that are scheduled for refactoring.
|
|
|
|
## Goroutine Leak (Mitigated)
|
|
|
|
### Symptom
|
|
|
|
Each trace creation starts 2 goroutines that accumulate during rapid iterations:
|
|
|
|
1. `trace/pubsub.(*PubSub).forward()` - PubSub event forwarding
|
|
2. `trace.(*manager).startStateWorker()` - State machine worker
|
|
|
|
### Current Status
|
|
|
|
**Fixed in Feb 2026**: State worker now uses `for range` on the command channel,
|
|
which exits cleanly when `Release()` closes the channel. The three-step shutdown
|
|
sequence (atomic flag -> cancel -> close) ensures:
|
|
|
|
- No new commands are accepted after the flag is set
|
|
- In-flight `safeSend` calls unblock via `ctx.Done`
|
|
- Worker drains remaining buffered commands before exiting
|
|
|
|
### Residual Behavior
|
|
|
|
- PubSub `forward()` goroutine still exits asynchronously after `Stop()` closes its channel
|
|
- In rapid create/release loops, there may be a brief overlap where old goroutines
|
|
haven't exited before new ones start. This is normal Go async cleanup behavior.
|
|
- **NOT a true leak**: goroutines eventually exit (channels are closed)
|
|
|
|
### Impact on Tests
|
|
|
|
Memory leak tests use a 20KB/iteration threshold to accommodate this overhead:
|
|
|
|
| Test | Actual Growth | Threshold |
|
|
| ----------------- | -------------- | --------- |
|
|
| StandardMode | ~15 bytes/iter | 20 KB |
|
|
| BusinessScenarios | ~80 bytes/iter | 20 KB |
|
|
| NestedCalls | ~13 KB/iter | 20 KB |
|
|
|
|
## Memory Growth (Reduced)
|
|
|
|
### Symptom
|
|
|
|
Linear memory growth during trace operations.
|
|
|
|
### Current Status
|
|
|
|
**Improved in Feb 2026**: The state worker lifecycle fix eliminates the scenario
|
|
where the worker exits prematurely while the channel remains open, which could
|
|
cause command objects to accumulate in the buffer without being consumed.
|
|
|
|
The three-step shutdown ensures all buffered commands are processed before the
|
|
worker exits, reducing memory retention from unconsumed channel entries.
|
|
|
|
### Residual Growth Sources
|
|
|
|
- PubSub subscription objects (cleaned up on Stop)
|
|
- Driver I/O buffers (transient, GC-eligible)
|
|
- Trace node references in memory state (released on worker exit)
|
|
|
|
### Workaround
|
|
|
|
The 20KB threshold in memory leak tests accommodates known overhead while still
|
|
detecting severe leaks (50KB+ growth would indicate a real problem).
|
|
|
|
## Planned Refactoring
|
|
|
|
The Trace module is scheduled for further refactoring:
|
|
|
|
1. **Global Event Service**: Decouple event broadcasting from trace manager into
|
|
a process-level daemon (separate plan)
|
|
2. **Resource pooling**: Consider reusing trace resources to reduce allocation overhead
|
|
3. **PubSub synchronous cleanup**: Ensure forward() goroutine exits before Stop() returns
|
|
|
|
## Testing Notes
|
|
|
|
When running memory leak tests:
|
|
|
|
- `TestMemoryLeakStandardMode`: 20KB threshold
|
|
- `TestMemoryLeakBusinessScenarios`: 20KB threshold
|
|
- `TestMemoryLeakNestedCalls`: 20KB threshold
|
|
- `TestMemoryLeakNestedConcurrent`: 25KB threshold (concurrent + DB operations)
|
|
|
|
These thresholds are intentionally higher than actual growth to:
|
|
|
|
1. Accommodate CI environment variations
|
|
2. Allow for GC timing differences
|
|
3. Still catch severe leaks (50KB+ would be concerning)
|
|
|
|
## Related Files
|
|
|
|
- `trace/manager.go` - State machine and goroutine management
|
|
- `trace/state.go` - Channel-based state worker and safeSend
|
|
- `trace/trace.go` - Release() three-step shutdown
|
|
- `trace/pubsub/pubsub.go` - PubSub forwarding goroutine
|
|
- `trace/trace_lifecycle_test.go` - Boundary condition tests for shutdown races
|
|
- `trace/BUGFIX.md` - Detailed bug analysis and fix documentation
|
|
|
|
---
|
|
|
|
_Last updated: February 2026_
|