Skip to content

Commit

Permalink
batch sync events based on event beats (facebook#47147)
Browse files Browse the repository at this point in the history
Summary:

By batching sync events if multiple events are dispatched during sync rendering this will reduce the number of re-renders.

Changelog: [Internal]

Differential Revision: D64287526
  • Loading branch information
lyahdav authored and facebook-github-bot committed Oct 22, 2024
1 parent fc2f099 commit a8b2ed2
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ void EventBeat::request() const {
isRequested_ = true;
}

void EventBeat::requestSynchronous() const {
isSynchronousRequested_ = true;
request();
}

void EventBeat::setBeatCallback(BeatCallback beatCallback) {
beatCallback_ = std::move(beatCallback);
}
Expand All @@ -32,7 +37,7 @@ void EventBeat::induce() const {
isRequested_ = false;
isBeatCallbackScheduled_ = true;

runtimeScheduler_.scheduleWork(
auto beat = std::function<void(jsi::Runtime&)>(
[this, ownerBox = ownerBox_](jsi::Runtime& runtime) {
auto owner = ownerBox->owner.lock();
if (!owner) {
Expand All @@ -44,6 +49,13 @@ void EventBeat::induce() const {
beatCallback_(runtime);
}
});

if (isSynchronousRequested_) {
isSynchronousRequested_ = false;
runtimeScheduler_.executeNowOnTheSameThread(std::move(beat));
} else {
runtimeScheduler_.scheduleWork(std::move(beat));
}
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ class EventBeat {
*/
virtual void request() const;

/*
* Communicates to the Beat that a consumer is waiting synchronously for the
* coming beat.
*/
virtual void requestSynchronous() const;

/*
* The callback is must be called on the proper thread.
*/
Expand All @@ -90,6 +96,7 @@ class EventBeat {
private:
RuntimeScheduler& runtimeScheduler_;
mutable std::atomic<bool> isBeatCallbackScheduled_{false};
mutable std::atomic<bool> isSynchronousRequested_{false};
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ namespace facebook::react {
EventDispatcher::EventDispatcher(
const EventQueueProcessor& eventProcessor,
std::unique_ptr<EventBeat> eventBeat,
RuntimeScheduler& runtimeScheduler,
StatePipe statePipe,
std::weak_ptr<EventLogger> eventLogger)
: eventQueue_(
EventQueue(eventProcessor, std::move(eventBeat), runtimeScheduler)),
: eventQueue_(EventQueue(eventProcessor, std::move(eventBeat))),
statePipe_(std::move(statePipe)),
eventLogger_(std::move(eventLogger)) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class EventDispatcher {
EventDispatcher(
const EventQueueProcessor& eventProcessor,
std::unique_ptr<EventBeat> eventBeat,
RuntimeScheduler& runtimeScheduler,
StatePipe statePipe,
std::weak_ptr<EventLogger> eventLogger);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ namespace facebook::react {

EventQueue::EventQueue(
EventQueueProcessor eventProcessor,
std::unique_ptr<EventBeat> eventBeat,
RuntimeScheduler& runtimeScheduler)
std::unique_ptr<EventBeat> eventBeat)
: eventProcessor_(std::move(eventProcessor)),
eventBeat_(std::move(eventBeat)),
runtimeScheduler_(&runtimeScheduler) {
eventBeat_(std::move(eventBeat)) {
eventBeat_->setBeatCallback(
[this](jsi::Runtime& runtime) { onBeat(runtime); });
}
Expand Down Expand Up @@ -79,26 +77,14 @@ void EventQueue::enqueueStateUpdate(StateUpdate&& stateUpdate) const {
}

void EventQueue::onEnqueue() const {
if (synchronousAccessRequested_) {
// Sync flush has been scheduled, no need to request access to the runtime.
return;
}
eventBeat_->request();
}

void EventQueue::experimental_flushSync() const {
synchronousAccessRequested_ = true;
runtimeScheduler_->executeNowOnTheSameThread([this](jsi::Runtime& runtime) {
synchronousAccessRequested_ = false;
onBeat(runtime);
});
eventBeat_->requestSynchronous();
}

void EventQueue::onBeat(jsi::Runtime& runtime) const {
if (synchronousAccessRequested_) {
// Sync flush has been scheduled, let's yield to it.
return;
}
flushStateUpdates();
flushEvents(runtime);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ class EventQueue {
public:
EventQueue(
EventQueueProcessor eventProcessor,
std::unique_ptr<EventBeat> eventBeat,
RuntimeScheduler& runtimeScheduler);
std::unique_ptr<EventBeat> eventBeat);

/*
* Enqueues and (probably later) dispatch a given event.
Expand Down Expand Up @@ -75,10 +74,6 @@ class EventQueue {
mutable std::vector<RawEvent> eventQueue_;
mutable std::vector<StateUpdate> stateUpdateQueue_;
mutable std::mutex queueMutex_;

// TODO: T183075253
RuntimeScheduler* runtimeScheduler_;
mutable std::atomic_bool synchronousAccessRequested_{false};
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ Scheduler::Scheduler(
EventQueueProcessor(
eventPipe, eventPipeConclusion, statePipe, eventPerformanceLogger_),
std::move(eventBeat),
*runtimeScheduler,
statePipe,
eventPerformanceLogger_);

Expand Down

0 comments on commit a8b2ed2

Please sign in to comment.