Skip to content

♻️ clean up createBatch API before migrating to js-core#4802

Open
BenoitZugmeyer wants to merge 8 commits into
mainfrom
benoit/internalize-flush-controller
Open

♻️ clean up createBatch API before migrating to js-core#4802
BenoitZugmeyer wants to merge 8 commits into
mainfrom
benoit/internalize-flush-controller

Conversation

@BenoitZugmeyer

@BenoitZugmeyer BenoitZugmeyer commented Jun 17, 2026

Copy link
Copy Markdown
Member

Motivation

In preparation for moving createBatch to js-core, this PR reduces the
number of abstractions it leaks to callers. Previously, every entry-point
(startLogsBatch, startRumBatch, startTelemetryTransport, …) had to
manually wire up HttpRequest, FlushController, and PageMayExitObservable
— details that are really internal to the batch machinery. Internalizing them
makes createBatch a self-contained, easy-to-use primitive, and reduces the
surface that js-core would need to expose.

Changes

  • Make encoder optional, defaulting to createIdentityEncoder
  • Internalize HttpRequest creation (callers now pass endpoints + reportError)
  • Simplify reportError to accept a plain message string instead of a RawError, so we don't have to expose RawError (yet)
  • Rename PAGE_MAY_EXIT lifecycle event to PREPARE_URGENT_FLUSH to better reflect its semantics and make it slightly more runtime agnostic
  • Replace sessionExpireObservable on FlushController with a forceFlush(reason) method, so callers drive flush timing without being wired into the controller
  • Internalize FlushController and PageMayExitObservable; Batch now exposes forceFlush, flushObservable, and prepareUrgentFlushObservable directly

Test instructions

This is a pure refactoring — verify that the SDK initialises and sends events normally by loading the sandbox (yarn devhttp://localhost:8080) and checking that RUM and log events are dispatched as expected.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@BenoitZugmeyer BenoitZugmeyer changed the title ♻️ internalize flushController ♻️ clean up createBatch API before migrating to js-core Jun 17, 2026
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jun 17, 2026

Copy link
Copy Markdown

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 172.46 KiB 172.30 KiB -171 B -0.10%
Rum Profiler 8.22 KiB 8.22 KiB 0 B 0.00%
Rum Recorder 21.09 KiB 21.14 KiB +48 B +0.22%
Logs 54.47 KiB 54.27 KiB -202 B -0.36%
Rum Slim 129.97 KiB 129.83 KiB -141 B -0.11%
Worker 22.96 KiB 22.96 KiB 0 B 0.00%

@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Jun 17, 2026

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 1 Pipeline job failed

DataDog/browser-sdk | check-squash-into-staging   View in Datadog   GitLab

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 75.61%
Overall Coverage: 77.01% (+0.14%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 63e39dc | Docs | Datadog PR Page | Give us feedback!

@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/internalize-flush-controller branch 2 times, most recently from 1ddd0ad to 4fc2a8e Compare June 17, 2026 16:17
…ntityEncoder`

Callers that don't need a custom encoder (telemetry, logs, debugger) no
longer have to explicitly pass `createIdentityEncoder()`. Only callers
with a non-default encoder (e.g. deflate in RUM) need to specify it.
`createBatch` now creates the `HttpRequest` internally, which removes
boilerplate from every call site. The internal call is wrapped with
`mockable()` so the spec can still inject a transport mock via
`replaceMockable`.
The event payload also changes from `PageMayExitEvent` (`{ reason: PageExitReason }`)
to a new `UrgentFlushReason` type alias (= `PageExitReason`), so subscribers
receive the reason directly rather than a wrapped object.
…ceFlush` method

`sessionExpireObservable` was the only "external trigger" wired directly
into the flush controller, making it an awkward special case. Replacing it
with a generic `forceFlush(reason)` method (re-exposed on `Batch`) lets
callers decide when to flush and with what reason, keeping the flush
controller focused on its internal triggers (page exit, bytes/messages/duration
limits).
@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/internalize-flush-controller branch from 4fc2a8e to ccc7356 Compare June 19, 2026 10:00
@BenoitZugmeyer BenoitZugmeyer marked this pull request as ready for review June 19, 2026 14:28
@BenoitZugmeyer BenoitZugmeyer requested review from a team as code owners June 19, 2026 14:28
@BenoitZugmeyer

Copy link
Copy Markdown
Member Author

/to-staging

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Jun 19, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-06-19 14:29:19 UTC ℹ️ Start processing command /to-staging


2026-06-19 14:29:26 UTC ℹ️ Branch Integration: starting soon, merge expected in approximately 19m (p90)

Commit f1e50ae278 will soon be integrated into staging-25.


2026-06-19 14:29:41 UTC 🚨 Branch Integration: this merge request has conflicts which couldn't be solved automatically

We couldn't automatically merge the commit f1e50ae278 into staging-25!

To solve the conflicts directly in Github, click here to create a fix pull request.

Alternatively, you can also click here reset the integration branch or use the following Slack command: @devflow reset-branch -r browser-sdk -b staging-25

⚠️ Warning: This action will DELETE ALL COMMITS on the integration branch. This action cannot be undone.

@BenoitZugmeyer BenoitZugmeyer force-pushed the benoit/internalize-flush-controller branch from f1e50ae to 63e39dc Compare June 19, 2026 14:30

@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: f1e50ae278

ℹ️ 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".

endpoints,
reportError,
})
sessionExpireObservable.subscribe(() => batch.forceFlush('session_expire'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Unsubscribe the RUM session-expiry flush handler

When RUM is stopped or reinitialized, batch.stop() does not tear down this raw sessionExpireObservable subscription; the old callback keeps the stopped batch, encoder, and request state reachable and continues to run on future session expirations. Before this refactor the flush controller owned the session-expiry subscription and included it in its cleanup, so store the subscription here and include it in the returned stop path.

Useful? React with 👍 / 👎.

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.

This is fine, we don't stop rum

}),
})
const batch = createBatch({ endpoints, reportError })
sessionManager.expireObservable.subscribe(() => batch.forceFlush('session_expire'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Unsubscribe the logs session-expiry flush handler

When Logs is stopped or reinitialized, batch.stop() only removes the batch flush observer and leaves this sessionManager.expireObservable subscription registered. Each stopped instance therefore keeps its batch/request state alive and still executes on later session expirations; keep the subscription and unsubscribe it from the returned stop path alongside batch.stop().

Useful? React with 👍 / 👎.

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.

This is fine, we don't stop rum

@bdibon bdibon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It improves the whole batch / flush flow, very good!

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