Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
async_op.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <memory>
5#include <napi.h>
6#include <thread>
7#include <utility>
8
9namespace bb::nodejs {
10
11using async_fn = std::function<void(msgpack::sbuffer&)>;
12
28class AsyncOperation : public Napi::AsyncWorker {
29 public:
30 AsyncOperation(Napi::Env env, std::shared_ptr<Napi::Promise::Deferred> deferred, async_fn fn)
31 : Napi::AsyncWorker(env)
32 , _fn(std::move(fn))
33 , _deferred(std::move(deferred))
34 {}
35
40
41 ~AsyncOperation() override = default;
42
43 void Execute() override
44 {
45 try {
46 _fn(_result);
47 } catch (const std::exception& e) {
48 SetError(e.what());
49 } catch (...) {
50 // Catch any other exception type that's not derived from std::exception
51 // This ensures the promise is always rejected rather than leaving it hanging
52 SetError("Unknown exception occurred during async operation");
53 }
54 }
55
56 void OnOK() override
57 {
58 auto buf = Napi::Buffer<char>::Copy(Env(), _result.data(), _result.size());
59 _deferred->Resolve(buf);
60 }
61 void OnError(const Napi::Error& e) override { _deferred->Reject(e.Value()); }
62
63 private:
65 std::shared_ptr<Napi::Promise::Deferred> _deferred;
66 msgpack::sbuffer _result;
67};
68
85 public:
86 ThreadedAsyncOperation(Napi::Env env, std::shared_ptr<Napi::Promise::Deferred> deferred, async_fn fn)
87 : _fn(std::move(fn))
88 , _deferred(std::move(deferred))
89 {
90 // Create a no-op JS function as the TSFN target — we use the native callback form of BlockingCall
91 // to resolve/reject the promise, so the JS function is never actually called directly.
92 auto dummy = Napi::Function::New(env, [](const Napi::CallbackInfo&) {});
93 _completion_tsfn = Napi::ThreadSafeFunction::New(env, dummy, "ThreadedAsyncOpComplete", 0, 1);
94 }
95
100
102
103 void Queue()
104 {
105 std::thread([this]() {
106 try {
107 _fn(_result);
108 _success = true;
109 } catch (const std::exception& e) {
110 _error = e.what();
111 _success = false;
112 } catch (...) {
113 _error = "Unknown exception occurred during threaded async operation";
114 _success = false;
115 }
116
117 // Post completion back to the JS main thread
118 _completion_tsfn.BlockingCall(
119 this, [](Napi::Env env, Napi::Function /*js_callback*/, ThreadedAsyncOperation* op) {
120 if (op->_success) {
121 auto buf = Napi::Buffer<char>::Copy(env, op->_result.data(), op->_result.size());
122 op->_deferred->Resolve(buf);
123 } else {
124 auto error = Napi::Error::New(env, op->_error);
125 op->_deferred->Reject(error.Value());
126 }
127 // Release the TSFN and self-destruct
128 op->_completion_tsfn.Release();
129 delete op;
130 });
131 }).detach();
132 }
133
134 private:
136 std::shared_ptr<Napi::Promise::Deferred> _deferred;
137 Napi::ThreadSafeFunction _completion_tsfn;
138 msgpack::sbuffer _result;
139 bool _success = false;
140 std::string _error;
141};
142
143} // namespace bb::nodejs
Encapsulatest some work that can be done off the JavaScript main thread.
Definition async_op.hpp:28
AsyncOperation & operator=(AsyncOperation &&)=delete
void Execute() override
Definition async_op.hpp:43
AsyncOperation(AsyncOperation &&)=delete
AsyncOperation & operator=(const AsyncOperation &)=delete
AsyncOperation(const AsyncOperation &)=delete
~AsyncOperation() override=default
AsyncOperation(Napi::Env env, std::shared_ptr< Napi::Promise::Deferred > deferred, async_fn fn)
Definition async_op.hpp:30
void OnError(const Napi::Error &e) override
Definition async_op.hpp:61
std::shared_ptr< Napi::Promise::Deferred > _deferred
Definition async_op.hpp:65
msgpack::sbuffer _result
Definition async_op.hpp:66
Runs work on a dedicated std::thread instead of the libuv thread pool.
Definition async_op.hpp:84
ThreadedAsyncOperation & operator=(const ThreadedAsyncOperation &)=delete
ThreadedAsyncOperation(Napi::Env env, std::shared_ptr< Napi::Promise::Deferred > deferred, async_fn fn)
Definition async_op.hpp:86
ThreadedAsyncOperation(const ThreadedAsyncOperation &)=delete
std::shared_ptr< Napi::Promise::Deferred > _deferred
Definition async_op.hpp:136
ThreadedAsyncOperation & operator=(ThreadedAsyncOperation &&)=delete
Napi::ThreadSafeFunction _completion_tsfn
Definition async_op.hpp:137
ThreadedAsyncOperation(ThreadedAsyncOperation &&)=delete
uint8_t const * buf
Definition data_store.hpp:9
std::function< void(msgpack::sbuffer &)> async_fn
Definition async_op.hpp:11
STL namespace.