1515 * limitations under the License.
1616 */
1717#include " consumer_ack.h"
18+
19+ #include < cstdlib>
1820#include < exception>
19- #include " napi.h"
21+
22+ #include < napi.h>
23+
24+ #include " addon_data.h"
2025
2126namespace __node_rocketmq__ {
2227
23- static void DeleteFunctionReference (Napi::Env, Napi::FunctionReference* data) {
24- delete data;
28+ #if defined(ROCKETMQ_COVERAGE) || defined(ROCKETMQ_USE_STUB)
29+ namespace {
30+ bool IsEnvEnabled (const char * name) {
31+ const char * value = std::getenv (name);
32+ if (value == nullptr ) {
33+ return false ;
34+ }
35+ return value[0 ] != ' \0 ' && value[0 ] != ' 0' ;
36+ }
2537}
38+ #endif
2639
27- Napi::Object ConsumerAck::Init (Napi::Env env, Napi::Object exports) {
40+ Napi::Object ConsumerAck::Init (Napi::Env env, Napi::Object exports, AddonData* addon_data ) {
2841 Napi::Function func = DefineClass (
2942 env, " ConsumerAck" , {InstanceMethod<&ConsumerAck::Done>(" done" )});
3043
31- // Store the constructor in env to avoid memory leak
32- Napi::FunctionReference* constructor = new Napi::FunctionReference ();
33- *constructor = Napi::Persistent (func);
34- env.SetInstanceData <Napi::FunctionReference, DeleteFunctionReference>(constructor);
44+ addon_data->consumer_ack_constructor = Napi::Persistent (func);
3545
3646 exports.Set (" ConsumerAck" , func);
3747 return exports;
3848}
3949
4050Napi::Object ConsumerAck::NewInstance (Napi::Env env) {
41- Napi::Object obj = env.GetInstanceData <Napi::FunctionReference>()->New ({});
42- return obj;
51+ AddonData* addon_data = GetAddonData (env);
52+ #if defined(ROCKETMQ_COVERAGE) || defined(ROCKETMQ_USE_STUB)
53+ if (addon_data == nullptr || IsEnvEnabled (" ROCKETMQ_STUB_CONSUMER_ACK_NULL_ADDON_DATA" )) {
54+ #else
55+ if (addon_data == nullptr ) {
56+ #endif
57+ Napi::Error::New (env, " ConsumerAck constructor not initialized" ).ThrowAsJavaScriptException ();
58+ return Napi::Object ();
59+ }
60+ return addon_data->consumer_ack_constructor .New ({});
4361}
4462
4563ConsumerAck::ConsumerAck (const Napi::CallbackInfo& info)
@@ -49,34 +67,39 @@ void ConsumerAck::SetPromise(std::promise<bool>&& promise) {
4967 promise_ = std::move (promise);
5068}
5169
52- void ConsumerAck::Done (bool ack) {
53- try {
54- promise_.set_value (ack);
55- } catch (const std::future_error& e) {
56- // ignore
57- }
58- }
59-
6070void ConsumerAck::Done (std::exception_ptr exception) {
61- try {
62- promise_.set_exception (exception);
63- } catch (const std::future_error& e) {
64- // ignore
71+ if (!done_called_.exchange (true )) {
72+ try {
73+ promise_.set_exception (exception);
74+ } catch (const std::future_error&) {
75+ }
6576 }
6677}
6778
6879Napi::Value ConsumerAck::Done (const Napi::CallbackInfo& info) {
69- try {
70- if (info.Length () >= 1 ) {
71- Napi::Value ack = info[0 ];
72- if (ack.IsBoolean () && !ack.ToBoolean ()) {
73- Done (false );
74- return info.Env ().Undefined ();
75- }
80+ if (done_called_.exchange (true )) {
81+ return info.Env ().Undefined ();
82+ }
83+
84+ bool ack = true ;
85+ if (info.Length () >= 1 ) {
86+ Napi::Value ack_value = info[0 ];
87+ if (ack_value.IsBoolean () && !ack_value.ToBoolean ()) {
88+ ack = false ;
7689 }
77- Done (true );
78- } catch (const std::exception& e) {
79- // ignore
90+ }
91+
92+ #if defined(ROCKETMQ_COVERAGE) || defined(ROCKETMQ_USE_STUB)
93+ if (IsEnvEnabled (" ROCKETMQ_STUB_CONSUMER_ACK_FORCE_FUTURE_ERROR" )) {
94+ try {
95+ promise_.set_value (true );
96+ } catch (const std::future_error&) {
97+ }
98+ }
99+ #endif
100+ try {
101+ promise_.set_value (ack);
102+ } catch (const std::future_error&) {
80103 }
81104 return info.Env ().Undefined ();
82105}
0 commit comments