feat(telemetry): track per-feature usage counters on compile events#6519
Conversation
Introduce a typed FeatureName registry and `increment_feature` helper so runtime call sites (uploads, cookies, storage, models, lifespan tasks, shared state, dynamic routes) and the compile-time collector (state-manager mode, CORS, background event handlers) feed a uniform counters map into the compile event. Always emit every known key so zeros are distinguishable from missing detectors.
Greptile SummaryThis PR introduces a typed
Confidence Score: 3/5Safe to merge for application correctness, but the telemetry data it produces will be inaccurate in multi-compile (hot-reload) scenarios due to two merging bugs in the accounting layer. The reflex/utils/telemetry_accounting.py (_collect_features_used merge logic) and reflex/utils/telemetry_context.py (_recorded_features lifecycle) Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Import time / class definitions] -->|Cookie, SharedState, Model.add| B[increment_feature]
C[App setup / add_page] -->|dynamic routes| B
D[register_lifespan_task] -->|user tasks only| B
B -->|No active context| E[_recorded_features\nglobal dict]
B -->|Active context| F[ctx.features_used\nper-compile dict]
G[Compile starts] --> H[TelemetryContext created & entered]
H --> I[_compile_page / Upload.create] -->|upload_count| F
J[record_compile called] --> K[_collect_features_used]
E -->|features.update| K
L[_record_config_attestations\nstate-manager, CORS] --> K
M[_record_background_handler_count\nwalk user states] --> K
F -->|features.update OVERWRITES| K
K --> N[features_used snapshot\nall _KNOWN_FEATURES initialized to 0]
N --> O[PostHog compile event]
style E fill:#f9c,stroke:#c66
style F fill:#9cf,stroke:#66c
style K fill:#fc9,stroke:#c96
Reviews (1): Last reviewed commit: "feat(telemetry): track per-feature usage..." | Re-trigger Greptile |
Move TelemetryContext into reflex_base and drop the scattered `increment_feature` call sites in Upload, lifespan, shared state, storage classes, and Model. Compile-event collection now walks the live app (states, pages, config, ModelRegistry) at compile end so the counters reflect actual final state rather than import-time markers that could double-count under reload or get out of sync.
…collector Drop the intermediate ``_ComponentWalk`` TypedDict in favor of a plain tuple, pass the resolved ``Config`` and ``get_route_args`` into the feature collector instead of re-resolving them, and lean on the ``_KNOWN_FEATURES`` zero-fill to drop the redundant storage-counter seeding pass.
State classes that inherit Cookie/LocalStorage/SessionStorage fields were re-counting the parent's fields on each descendant. Walk only the fields declared on each class so the per-feature counters reflect distinct storage vars across the state tree.
Co-authored-by: Masen Furer <m_github@0x26.net>
Rename `_TelAcct*`, `_Storage*`, `_Shared*`, `_BgState`, `_UserWalkState`, `_StubMemoWrapper`, and `_PlainStub` to their non-underscored equivalents, and construct `Upload`/`StyledUpload` via `create()` instead of `object.__new__`.
…/reflex into telemetry-features
The compile-event walk was paying for an ``isinstance(node, Upload)`` on every component in every page tree to derive ``upload_count``, which profiled at ~20% of total walk overhead. ``Upload.is_used`` is already maintained by upload call sites for the upload-endpoint mount gate; read it directly off the class instead. - Restore ``_count_components`` to its single-purpose, class-name-only shape (no tuple return, no Upload special case). - Drop the ``upload_count`` parameter from ``_collect_features_used``; it now reads ``int(Upload.is_used)``. - No change to ``Upload`` itself.
ed5e58d to
d136224
Compare
|
we can keep the walk for now, overall it's not contributing a significant amount to the runtime; we can optimize it later if it turns out to be more significant |
issue was fixed and Alek is at BTS concert
Introduce a typed FeatureName registry and
increment_featurehelper so runtime call sites (uploads, cookies, storage, models, lifespan tasks, shared state, dynamic routes) and the compile-time collector (state-manager mode, CORS, background event handlers) feed a uniform counters map into the compile event. Always emit every known key so zeros are distinguishable from missing detectors.All Submissions:
Type of change
Please delete options that are not relevant.
New Feature Submission:
Changes To Core Features:
fixes ENG-9480