Skip to content

RUM-16394 Pt.3: Wire Quota Checker with Profiling Feature#3538

Merged
ambushwork merged 1 commit into
feature/continuous-profilingfrom
yl/profiling/quota-api
Jun 18, 2026
Merged

RUM-16394 Pt.3: Wire Quota Checker with Profiling Feature#3538
ambushwork merged 1 commit into
feature/continuous-profilingfrom
yl/profiling/quota-api

Conversation

@ambushwork

@ambushwork ambushwork commented Jun 12, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Connects the ProfilingQuotaChecker to the Profiling Feature so profiling is gated on the backend quota decision, and surfaces the quota outcome on RUM events.

Motivation

  • Profiling feature
    • On each new RUM session, ProfilingFeature fires an async quota check (createOkHttpCallFactory + dedicated single-thread executor, 5s call timeout).
    • Launch profiling holds its buffered result until the quota decision arrives (or the timeout fallback fails open); on DENIED the launch event is dropped, otherwise it's written. Continuous profiling skips its active window (stays in cooldown) when the decision is DENIED.
    • The denied reason is propagated into the profiling feature context (PROFILING_QUOTA_REASON) and cleared when allowed; onStop tears the checker/executor down cleanly.
  • RUM
    • RumViewScope (Error / Long Task) and the app-launch vital now report profiling.status = STOPPED with quota_reason when profiling was denied by quota, and RUNNING otherwise. Reading profiling state was simplified to go straight through the feature context.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@datadog-official

This comment has been minimized.

@ambushwork
ambushwork force-pushed the yl/profiling/quota-api branch from fea1964 to 7c1603d Compare June 12, 2026 14:58
@codecov-commenter

codecov-commenter commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.22222% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.46%. Comparing base (7944881) to head (2aa78ac).

Files with missing lines Patch % Lines
...dog/android/profiling/internal/ProfilingFeature.kt 90.70% 1 Missing and 3 partials ⚠️
.../rum/internal/profiling/ProfilingFeatureContext.kt 66.67% 0 Missing and 2 partials ⚠️
...ernal/domain/scope/RumVitalAppLaunchEventHelper.kt 66.67% 1 Missing ⚠️
Additional details and impacted files
@@                       Coverage Diff                        @@
##           feature/continuous-profiling    #3538      +/-   ##
================================================================
+ Coverage                         72.45%   72.46%   +0.02%     
================================================================
  Files                               986      987       +1     
  Lines                             36513    36579      +66     
  Branches                           6077     6093      +16     
================================================================
+ Hits                              26452    26506      +54     
  Misses                             8406     8406              
- Partials                           1655     1667      +12     
Files with missing lines Coverage Δ
...profiling/internal/ContinuousProfilingScheduler.kt 92.31% <100.00%> (+3.42%) ⬆️
.../android/rum/internal/domain/scope/RumViewScope.kt 94.62% <100.00%> (-0.47%) ⬇️
.../internal/startup/RumSessionScopeStartupManager.kt 95.21% <100.00%> (+0.31%) ⬆️
...ernal/domain/scope/RumVitalAppLaunchEventHelper.kt 88.78% <66.67%> (-0.81%) ⬇️
.../rum/internal/profiling/ProfilingFeatureContext.kt 66.67% <66.67%> (ø)
...dog/android/profiling/internal/ProfilingFeature.kt 85.56% <90.70%> (+3.04%) ⬆️

... and 39 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ambushwork

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c1603d123

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ambushwork
ambushwork force-pushed the yl/profiling/quota-api branch 2 times, most recently from 853fe02 to 2521419 Compare June 16, 2026 07:40
@ambushwork
ambushwork marked this pull request as ready for review June 16, 2026 08:37
@ambushwork
ambushwork requested review from a team as code owners June 16, 2026 08:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 252141911d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ambushwork
ambushwork force-pushed the yl/profiling/quota-api branch from 2521419 to 06b58d4 Compare June 17, 2026 09:11
@ambushwork
ambushwork force-pushed the yl/profiling/quota-api branch from 06b58d4 to 2aa78ac Compare June 17, 2026 09:12
val quotaCallFactory = sdkCore.createOkHttpCallFactory {
callTimeout(QUOTA_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
}
val qExecutor = sdkCore.createSingleThreadExecutorService(QUOTA_EXECUTOR_CONTEXT)

@0xnm 0xnm Jun 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it is worth reusing existing uploadExecutorService executor or executor for the profiling? The latter is used to run only profiling submission tasks, which are short and quick, so it has plenty of room for another scheduling.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is not profiling submission block quota checker, but oppositely the network request in QuotaCheck can block the profiling submission, which might disorder the continuous profiling cycle or callback of ProfilingManager.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the network request in QuotaCheck can block the profiling submission

I guess this is the case for the Profiling executor, but what about uploadExecutorService then?

@ambushwork ambushwork Jun 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, using uploadExecutorService doesn't have this problem, but I don't think ProfilingFeature has access to uploadExecutorService in the CoreFeature

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not exposed via API, but it is not a problem with exposing it somehow. Or we can use InternalSdkCore.getPersistenceExecutorService for that (hacky, but works).

Realistically we create a thread just to run (once per session, ideally) a quick task, and most of the time it will be idling. SDK has already too much threads and we must pack work across existing threads.

We can keep the current approach, but we need to revisit it later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the sample app I found 14 threads belonging to Datadog SDK, roughly 30% don't have any work (measuring the first few seconds of app start).

image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just let Claude investigate the source code for the same purpose, here is the result:

With all features enabled, roughly 19–24 threads per SDK instance:

  • Core: 4 (shared, justified)
  • RUM: ~6 (pipeline, anr, vital, + one per active tracking strategy)
  • Profiling: 2
  • Session Replay: 3–12 (resource pool scales 1→10)
  • Flags: 2
  • Trace: 3 (some are process-wide singletons, not per-instance)

Smells like an Android Guild task, I will create a ticket

@ambushwork
ambushwork merged commit 0ceaec7 into feature/continuous-profiling Jun 18, 2026
27 checks passed
@ambushwork
ambushwork deleted the yl/profiling/quota-api branch June 18, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants