Commit 32efa23
feat(core): Aggregate TurboModule call counts and latency per (module, method, kind) (#6377)
* feat(core): Aggregate TurboModule call counts and latency per (module, method, kind)
Adds a small fixed-bucket histogram + counters per `(module, method, kind)`
fed by the existing `wrapTurboModule` instrumentation. Aggregates flush on
transaction finish (synthetic `turbo_modules.aggregate` child span + headline
measurements on the root span) and on a lazy timer (info-level event for
long-running sessions without transactions).
Closes #6164.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* test(core): Trim TurboModule aggregator tests to the basics
Drop edge-case tests in favor of one happy-path check per surface.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(core): Break TurboModule aggregator self-flush loop
The periodic flush's own `captureEvent` travels through the wrapped
`RNSentry.captureEnvelope`, which records back into the aggregator and,
because the map was just drained, re-armed the flush timer forever in
otherwise-idle sessions. Suppress the empty→non-empty callback around
the flush's `captureEvent`, deferring the release to the next macrotask
so the async record fired from the transport's `.then()` also lands
inside the suppression window.
* fix(core): Stop aggregating TurboModule calls when stats disabled
`enableAggregateStats: false` skipped flush setup and processEvent but
`wrapTurboModule` still recorded every call into the process-wide map,
which had no drain path in that mode — so counters grew for the app's
lifetime. Aggregator now exposes a master `setAggregateRecordingEnabled`
switch that both no-ops future records and evicts existing entries.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(core): Drain aggregator noise after periodic flush suppression
The suppression window in `flushPeriodicAggregate` prevented the flush's
own transport call from re-arming the timer, but left the recorded
self-noise sitting in the aggregate map. The next real user call then
saw `wasEmpty=false` and never fired `onFirstRecordAfterEmpty`, so the
periodic timer stayed silent for the rest of the session (until a
transaction drain cleared the leftover).
Drain the aggregator when releasing the suppression scope. Trades a
sub-millisecond window of possibly-real user records for a working
lazy-timer re-arm on every subsequent call.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(core): Default-ignore RNSentry in TurboModule aggregate
The previous suppression + drain machinery worked around the flush's
own `captureEvent → RNSentry.captureEnvelope` self-noise by drop-listing
records around the send. That approach had two follow-on bugs: the
blanket drain also discarded real user calls that raced with the flush
window, and the async transport `.then()` sometimes fired outside the
suppression scope entirely.
Move the fix upstream: default `ignoreTurboModules` to `['RNSentry']`.
Self-noise never enters the aggregator, so no suppression/drain gymnastics
are needed. Users who want RNSentry stats can pass `ignoreTurboModules: []`.
Also document the intentional data-loss trade-off when a transaction is
dropped by `beforeSendTransaction` (bounded, self-healing on the next
transaction or periodic flush).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(core): Drop unused isTurboModuleIgnored helper
Nothing in the package reads it — `recordTurboModuleCall` checks the
ignored set inline. Removing dead API surface.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: LucasZF <lucas-zimerman1@hotmail.com>1 parent 63b8285 commit 32efa23
11 files changed
Lines changed: 940 additions & 14 deletions
File tree
- packages/core
- etc
- src/js
- integrations
- turbomodule
- test
- integrations
- turbomodule
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
13 | 30 | | |
14 | 31 | | |
15 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
856 | 856 | | |
857 | 857 | | |
858 | 858 | | |
859 | | - | |
| 859 | + | |
860 | 860 | | |
861 | 861 | | |
862 | 862 | | |
863 | 863 | | |
864 | 864 | | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
865 | 868 | | |
866 | 869 | | |
867 | 870 | | |
868 | 871 | | |
869 | 872 | | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
870 | 876 | | |
871 | 877 | | |
872 | 878 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
175 | | - | |
| 175 | + | |
0 commit comments