Skip to content

Replace merge commit scheduling with a run loop observer (#56726)#56726

Open
j-piasecki wants to merge 1 commit intofacebook:mainfrom
j-piasecki:export-D104227839
Open

Replace merge commit scheduling with a run loop observer (#56726)#56726
j-piasecki wants to merge 1 commit intofacebook:mainfrom
j-piasecki:export-D104227839

Conversation

@j-piasecki
Copy link
Copy Markdown
Contributor

@j-piasecki j-piasecki commented May 8, 2026

Summary:

Changelog: [IOS][CHANGED] - Drain React-revision merges from a BeforeWaiting main run loop observer instead of dispatching each merge as a separate main-queue block

With Fabric commit branching (enableFabricCommitBranching), React commits land on a forked currentReactRevision_ and are merged into the main branch later via ShadowTree::mergeReactRevision(). On iOS, the schedulerShouldMergeReactRevision: callback used to do a plain RCTExecuteOnMainQueue per promotion, so every promotion enqueued a fresh main queue block that competed for ordering with mount blocks dispatched from concurrent commits with mountSynchronously=true.

Instead of dispatching each merge as its own main-queue block, enqueue the surface id into an unordered_set<SurfaceId> and drain it from a MainRunLoopObserver registered at kCFRunLoopBeforeWaiting. The merge calls ShadowTree::commit(..., mountSynchronously = true), so the mount completes inline before the observer returns.

A similar mechanism has already been implemented on Android in D100966623

Reviewed By: javache

Differential Revision: D104227839

@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 8, 2026

@j-piasecki has exported this pull request. If you are a Meta employee, you can view the originating Diff in D104227839.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 8, 2026
@facebook-github-tools facebook-github-tools Bot added p: Software Mansion Partner: Software Mansion Partner p: Facebook Partner: Facebook labels May 8, 2026
@meta-codesync meta-codesync Bot changed the title Replace merge commit schediling with a run loop observer Replace merge commit scheduling with a run loop observer May 8, 2026
@j-piasecki j-piasecki force-pushed the export-D104227839 branch from 94d33e3 to 0c5c210 Compare May 8, 2026 09:19
@meta-codesync meta-codesync Bot changed the title Replace merge commit scheduling with a run loop observer Replace merge commit scheduling with a run loop observer (#56726) May 8, 2026
j-piasecki added a commit to j-piasecki/react-native that referenced this pull request May 8, 2026
)

Summary:

Changelog: [IOS][CHANGED] - Drain React-revision merges from a `BeforeWaiting` main run loop observer instead of dispatching each merge as a separate main-queue block

With Fabric commit branching (`enableFabricCommitBranching`), React commits land on a forked `currentReactRevision_` and are merged into the main branch later via `ShadowTree::mergeReactRevision()`. On iOS, the `schedulerShouldMergeReactRevision:` callback used to do a plain `RCTExecuteOnMainQueue` per promotion, so every promotion enqueued a fresh main queue block that competed for ordering with mount blocks dispatched from concurrent commits with `mountSynchronously=true`.

Instead of dispatching each merge as its own main-queue block, enqueue the surface id into an `unordered_set<SurfaceId>` and drain it from a `MainRunLoopObserver` registered at `kCFRunLoopBeforeWaiting`. The merge calls `ShadowTree::commit(..., mountSynchronously = true)`, so the mount completes inline before the observer returns.

A similar mechanism has already been implemented on Android in D100966623

Reviewed By: javache

Differential Revision: D104227839
@j-piasecki j-piasecki force-pushed the export-D104227839 branch from 0c5c210 to 3b290ea Compare May 8, 2026 11:17
)

Summary:

Changelog: [IOS][CHANGED] - Drain React-revision merges from a `BeforeWaiting` main run loop observer instead of dispatching each merge as a separate main-queue block

With Fabric commit branching (`enableFabricCommitBranching`), React commits land on a forked `currentReactRevision_` and are merged into the main branch later via `ShadowTree::mergeReactRevision()`. On iOS, the `schedulerShouldMergeReactRevision:` callback used to do a plain `RCTExecuteOnMainQueue` per promotion, so every promotion enqueued a fresh main queue block that competed for ordering with mount blocks dispatched from concurrent commits with `mountSynchronously=true`.

Instead of dispatching each merge as its own main-queue block, enqueue the surface id into an `unordered_set<SurfaceId>` and drain it from a `MainRunLoopObserver` registered at `kCFRunLoopBeforeWaiting`. The merge calls `ShadowTree::commit(..., mountSynchronously = true)`, so the mount completes inline before the observer returns.

A similar mechanism has already been implemented on Android in D100966623

Reviewed By: javache

Differential Revision: D104227839
@j-piasecki j-piasecki force-pushed the export-D104227839 branch from 3b290ea to 5097abd Compare May 8, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported p: Facebook Partner: Facebook p: Software Mansion Partner: Software Mansion Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant