diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-24 12:12:31 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-24 12:12:31 +0200 |
| commit | 610d91472b3b37010130f33bd835c23e859caf56 (patch) | |
| tree | 48cc2cb7e425c69135095ad748389afd0192c4d1 /internal/statsengine/syscall.go | |
| parent | 0d4ef22478a470d86ce907beedcaa726d0d46c73 (diff) | |
statsengine: build snapshots outside engine mutex
Diffstat (limited to 'internal/statsengine/syscall.go')
| -rw-r--r-- | internal/statsengine/syscall.go | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/internal/statsengine/syscall.go b/internal/statsengine/syscall.go index b3b8c4c..fe54cb4 100644 --- a/internal/statsengine/syscall.go +++ b/internal/statsengine/syscall.go @@ -32,6 +32,18 @@ type syscallStats struct { samples []uint64 } +type syscallSnapshotInput struct { + traceID types.TraceId + name string + count uint64 + errorCount uint64 + totalBytes uint64 + totalLatency uint64 + minLatency uint64 + maxLatency uint64 + sortedSamples []uint64 +} + func newSyscallAccumulator() *syscallAccumulator { return newSyscallAccumulatorWithConfig(syscallReservoirSampleCapDefault, rand.New(rand.NewSource(time.Now().UnixNano()))) } @@ -79,19 +91,45 @@ func (a *syscallAccumulator) Snapshot(elapsed time.Duration) []SyscallSnapshot { return nil } - rateDiv := elapsed.Seconds() - result := make([]SyscallSnapshot, 0, len(a.byID)) - for _, stats := range a.byID { - result = append(result, stats.toSnapshot(rateDiv)) + return buildSyscallSnapshots(a.snapshotInputs(), elapsed) +} + +func (a *syscallAccumulator) snapshotInputs() []syscallSnapshotInput { + if a == nil { + return nil } + inputs := make([]syscallSnapshotInput, 0, len(a.byID)) + for _, stats := range a.byID { + sorted := append([]uint64(nil), stats.samples...) + sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) + inputs = append(inputs, syscallSnapshotInput{ + traceID: stats.traceID, + name: stats.name, + count: stats.count, + errorCount: stats.errorCount, + totalBytes: stats.totalBytes, + totalLatency: stats.totalLatency, + minLatency: stats.minLatency, + maxLatency: stats.maxLatency, + sortedSamples: sorted, + }) + } + return inputs +} + +func buildSyscallSnapshots(inputs []syscallSnapshotInput, elapsed time.Duration) []SyscallSnapshot { + rateDiv := elapsed.Seconds() + result := make([]SyscallSnapshot, 0, len(inputs)) + for _, in := range inputs { + result = append(result, in.toSnapshot(rateDiv)) + } sort.Slice(result, func(i, j int) bool { if result[i].Count != result[j].Count { return result[i].Count > result[j].Count } return result[i].Name < result[j].Name }) - return result } @@ -118,12 +156,7 @@ func (s *syscallStats) addSample(duration uint64, cap int, rng *rand.Rand) { s.samples[idx] = duration } -func (s *syscallStats) toSnapshot(rateDiv float64) SyscallSnapshot { - sortedSamples := append([]uint64(nil), s.samples...) - sort.Slice(sortedSamples, func(i, j int) bool { - return sortedSamples[i] < sortedSamples[j] - }) - +func (s syscallSnapshotInput) toSnapshot(rateDiv float64) SyscallSnapshot { return SyscallSnapshot{ TraceID: s.traceID, Name: s.name, @@ -134,9 +167,9 @@ func (s *syscallStats) toSnapshot(rateDiv float64) SyscallSnapshot { LatencyMinNs: s.minLatency, LatencyMaxNs: s.maxLatency, LatencyMeanNs: float64(s.totalLatency) / float64(maxU64(s.count, 1)), - LatencyP50Ns: samplePercentile(sortedSamples, 0.50), - LatencyP95Ns: samplePercentile(sortedSamples, 0.95), - LatencyP99Ns: samplePercentile(sortedSamples, 0.99), + LatencyP50Ns: samplePercentile(s.sortedSamples, 0.50), + LatencyP95Ns: samplePercentile(s.sortedSamples, 0.95), + LatencyP99Ns: samplePercentile(s.sortedSamples, 0.99), } } |
