mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
dffec8bc7b
Summary: Changelog: [internal] In D22940187 (https://github.com/facebook/react-native/commit/774dec1e17f6f250172a6d4d944121b82fa36efb) we introduced a mechanism to retry failed state updates from view layer. The mechanism fixes an issue where state update is occasionally dropped with background executor enabled. # Why is state dropped? The state is dropped because with background executor enabled, it is possible to enter `ShadowTree::tryCommit` for the same tree from 2 different threads at once. One of thread changes `_rootShadowNode` causing the other commit to fail. The code goes like this: ``` { Lock mutex grab reference to `rootShadowNode_` and call it `oldRootShadowNode` Unlock mutex } State reconciliation Trigger layout `rootShadowNode_` is untouched in this section. { Lock mutex Check if `oldRootShadowNode` is equal to `rootShadowNode_`, if not, return false signalling failure. Now this is what happens when state update fails. ..... not relevant Unlock mutex } ..... not relevant ``` However, in D22940187 (https://github.com/facebook/react-native/commit/774dec1e17f6f250172a6d4d944121b82fa36efb), we have taken another path. Instead of retrying to commit transaction, client is informed about the failure and it is left up to them to retry. This is correct and works. But I think it is unnecessary to this retry can be done inside UIManager::updateState. In this diff I call `ShadowTree::commit` (version with retries) in case no `stateUpdate.failureCallback` is provided. This makes sure that we do retry if state update fails but if Android implements `stateUpdate.failureCallback`, it is left up to view layer to retry. Eventually we might decide to converge these two approaches. Reviewed By: shergin Differential Revision: D23151218 fbshipit-source-id: 5cb78a3a75a754429a8e33bd7736e683e9ed34d4