Skip to content

feat(Worklets): runAsyncGuardedOnUI #7906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2dcb70a
feat(Worklets): allow passing user-implemented AsyncQueue to createWo…
tjzel Jul 22, 2025
25a8519
Merge branch 'main' into @tjzel/worklets/runtime-async-queue
tjzel Jul 24, 2025
f14c37a
feat(Worklets): make AsyncQueue virtual and public
tjzel Jul 24, 2025
66d5c69
chore: remove import
tjzel Jul 24, 2025
1facc19
Merge branch 'main' into @tjzel/worklets/runtime-async-queue
tjzel Jul 24, 2025
196ff99
Merge branch '@tjzel/worklets/virtual-async-queue' into @tjzel/workle…
tjzel Jul 24, 2025
d7d06c7
chore: wip
tjzel Jul 24, 2025
217abc9
chore: merge main
tjzel Jul 25, 2025
4c33ff0
chore: wip
tjzel Jul 25, 2025
16f80bc
refactor(Worklets): remove supportsLocking parameter from Worklet Run…
tjzel Jul 25, 2025
6cc99a5
refactor(Worklets): extract RuntimeData file
tjzel Jul 25, 2025
db700ec
Merge branch '@tjzel/worklets/runtime-lock' into @tjzel/worklets/runt…
tjzel Jul 25, 2025
e1fd780
Merge branch '@tjzel/worklets/runtime-data' into @tjzel/worklets/runt…
tjzel Jul 25, 2025
c766715
Merge branch '@tjzel/worklets/runtime-lock' into @tjzel/worklets/runt…
tjzel Jul 25, 2025
2c75ae2
chore: js API
tjzel Jul 25, 2025
5d48fab
feat(Worklets): runAsyncGuarded on UI
tjzel Jul 25, 2025
c2c1b1f
chore: initialize queue
tjzel Jul 25, 2025
295a69e
Merge branch 'main' into @tjzel/worklets/runtime-lock
tjzel Jul 29, 2025
be4b62e
chore: cleanup
tjzel Jul 29, 2025
b75c728
Merge branch '@tjzel/worklets/runtime-lock' into @tjzel/worklets/runt…
tjzel Jul 29, 2025
dcaafe9
chore: fix CI
tjzel Jul 29, 2025
7ca0c73
Merge branch 'main' into @tjzel/worklets/runtime-async-queue
tjzel Jul 29, 2025
b0dcb78
Merge branch '@tjzel/worklets/runtime-async-queue' into @tjzel/workle…
tjzel Jul 29, 2025
215815a
chore: merge main
tjzel Jul 30, 2025
899307a
chore: cleanup & review changes
tjzel Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <worklets/NativeModules/WorkletsModuleProxy.h>
#include <worklets/SharedItems/Shareables.h>
#include <worklets/Tools/AsyncQueueImpl.h>
#include <worklets/Tools/Defs.h>
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>

Expand Down Expand Up @@ -40,8 +41,9 @@ WorkletsModuleProxy::WorkletsModuleProxy(
script_(script),
sourceUrl_(sourceUrl),
runtimeManager_(std::make_shared<RuntimeManager>()),
uiWorkletRuntime_(
runtimeManager_->createUninitializedUIRuntime(jsQueue_)) {
uiWorkletRuntime_(runtimeManager_->createUninitializedUIRuntime(
jsQueue_,
std::make_shared<AsyncQueueUI>(uiScheduler_))) {
/**
* We call additional `init` method here because
* JSIWorkletsModuleProxy needs a weak_ptr to the UI Runtime.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,11 @@ void AsyncQueueImpl::push(std::function<void()> &&job) {
state_->cv.notify_one();
}

AsyncQueueUI::AsyncQueueUI(const std::shared_ptr<UIScheduler> &uiScheduler)
: uiScheduler_(uiScheduler) {}

void AsyncQueueUI::push(std::function<void()> &&job) {
uiScheduler_->scheduleOnUI(std::move(job));
}

} // namespace worklets
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <jsi/jsi.h>
#include <worklets/Public/AsyncQueue.h>
#include <worklets/Tools/UIScheduler.h>

#include <atomic>
#include <condition_variable>
Expand Down Expand Up @@ -30,4 +31,16 @@ class AsyncQueueImpl : public AsyncQueue {
const std::shared_ptr<AsyncQueueState> state_;
};

class AsyncQueueUI : public AsyncQueue {
public:
explicit AsyncQueueUI(const std::shared_ptr<UIScheduler> &uiScheduler);

~AsyncQueueUI() override = default;

void push(std::function<void()> &&job) override;

private:
std::shared_ptr<UIScheduler> uiScheduler_;
};

} // namespace worklets
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ std::shared_ptr<WorkletRuntime> RuntimeManager::createWorkletRuntime(
}

std::shared_ptr<WorkletRuntime> RuntimeManager::createUninitializedUIRuntime(
const std::shared_ptr<MessageQueueThread> &jsQueue) {
const auto uiRuntime =
std::make_shared<WorkletRuntime>(uiRuntimeId, jsQueue, uiRuntimeName);
const std::shared_ptr<MessageQueueThread> &jsQueue,
const std::shared_ptr<AsyncQueue> &uiAsyncQueue) {
const auto uiRuntime = std::make_shared<WorkletRuntime>(
uiRuntimeId, jsQueue, uiRuntimeName, uiAsyncQueue);
std::unique_lock lock(weakRuntimesMutex_);
weakRuntimes_[uiRuntimeId] = uiRuntime;
return uiRuntime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class RuntimeManager {
const std::shared_ptr<AsyncQueue> &queue = nullptr);

std::shared_ptr<WorkletRuntime> createUninitializedUIRuntime(
const std::shared_ptr<MessageQueueThread> &jsQueue);
const std::shared_ptr<MessageQueueThread> &jsQueue,
const std::shared_ptr<AsyncQueue> &uiAsyncQueue);

private:
uint64_t getNextRuntimeId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ void WorkletRuntime::init(
#endif // WORKLETS_BUNDLE_MODE
}

void WorkletRuntime::runAsyncGuarded(
const std::shared_ptr<SerializableWorklet> &worklet) {
react_native_assert(
"[Worklets] Tried to invoke `runAsyncGuarded` on a Worklet Runtime but "
"the async queue is not set. Recreate the runtime with a valid async queue.");

queue_->push([worklet, weakThis = weak_from_this()] {
auto strongThis = weakThis.lock();
if (!strongThis) {
return;
}

strongThis->runGuarded(worklet);
});
}

jsi::Value WorkletRuntime::executeSync(
jsi::Runtime &rt,
const jsi::Value &worklet) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,7 @@ class WorkletRuntime : public jsi::HostObject,
rt, serializableWorklet->toJSValue(rt), std::forward<Args>(args)...);
}

void runAsyncGuarded(
const std::shared_ptr<SerializableWorklet> &serializableWorklet) {
react_native_assert(
"[Worklets] Tried to invoke `runAsyncGuarded` on a Worklet Runtime but "
"the async queue is not set. Recreate the runtime with a valid async queue.");
queue_->push([=, weakThis = weak_from_this()] {
auto strongThis = weakThis.lock();
if (!strongThis) {
return;
}

strongThis->runGuarded(serializableWorklet);
});
}
void runAsyncGuarded(const std::shared_ptr<SerializableWorklet> &worklet);

jsi::Value executeSync(jsi::Runtime &rt, const jsi::Value &worklet) const;

Expand Down
Loading