@@ -41,105 +41,55 @@ static const std::map<std::string, pulsar_consumer_type> SUBSCRIPTION_TYPE = {
41
41
{" Failover" , pulsar_ConsumerFailover}};
42
42
43
43
struct MessageListenerProxyData {
44
- pulsar_consumer_t *cConsumer ;
44
+ std::shared_ptr<CConsumerWrapper> consumerWrapper ;
45
45
pulsar_message_t *cMessage;
46
- std::mutex mutex;
47
- std::condition_variable cv;
48
- bool finished;
49
46
50
- MessageListenerProxyData (pulsar_consumer_t *cConsumer, pulsar_message_t *cMessage)
51
- : cConsumer(cConsumer), cMessage(cMessage), finished(false ) {}
52
-
53
- void Wait () {
54
- std::unique_lock<std::mutex> lk (this ->mutex );
55
- this ->cv .wait (lk, [=]() { return this ->finished ; });
56
- }
57
-
58
- void Notify () {
59
- std::lock_guard<std::mutex> lk (this ->mutex );
60
- this ->finished = true ;
61
- this ->cv .notify_all ();
62
- }
63
-
64
- bool Finished () {
65
- std::lock_guard<std::mutex> lk (this ->mutex );
66
- return this ->finished ;
67
- }
47
+ MessageListenerProxyData (std::shared_ptr<CConsumerWrapper> consumerWrapper, pulsar_message_t *cMessage)
48
+ : consumerWrapper(consumerWrapper), cMessage(cMessage) {}
68
49
};
69
50
70
51
void Acknowledge (const Napi::CallbackInfo &info) {
71
52
Napi::Object obj = info[0 ].As <Napi::Object>();
72
53
Message *msg = Message::Unwrap (obj);
73
- std::shared_ptr<MessageListenerProxyData> *listenerData =
74
- (std::shared_ptr<MessageListenerProxyData> *)info.Data ();
54
+ MessageListenerProxyData *listenerData = (MessageListenerProxyData *)info.Data ();
75
55
// We can't use the consumer after it has been notified, the consumer will be destrotyed after the first
76
56
// time we call notify
77
- if (!(*listenerData)->Finished ()) {
78
- pulsar_consumer_acknowledge_async ((*listenerData)->cConsumer , msg->GetCMessage (), NULL , NULL );
79
- }
80
- (*listenerData)->Notify ();
81
- }
82
-
83
- void NegativeAcknowledge (const Napi::CallbackInfo &info) {
84
- std::shared_ptr<MessageListenerProxyData> *listenerData =
85
- (std::shared_ptr<MessageListenerProxyData> *)info.Data ();
86
- // Nack isn't available on the C client version 2.3.0
87
- // This just releases the message listener thread
88
- (*listenerData)->Notify ();
57
+ pulsar_consumer_acknowledge_async (listenerData->consumerWrapper ->cConsumer , msg->GetCMessage (), NULL , NULL );
89
58
}
90
59
91
60
void FinalizeMessageListenerProxy (napi_env env, void *data, void *) {
92
- std::shared_ptr<MessageListenerProxyData> *listenerData = (std::shared_ptr<MessageListenerProxyData> *)data;
93
- (*listenerData)->Notify ();
61
+ MessageListenerProxyData *listenerData = (MessageListenerProxyData *)data;
94
62
delete listenerData;
95
63
}
96
64
97
- void MessageListenerProxy (Napi::Env env, Napi::Function jsCallback,
98
- std::shared_ptr<MessageListenerProxyData> *data) {
99
- Napi::Object obj = Message::NewInstance ({}, (*data)->cMessage );
100
- std::shared_ptr<MessageListenerProxyData> *dataCopy = new std::shared_ptr<MessageListenerProxyData>(*data);
65
+ void MessageListenerProxy (Napi::Env env, Napi::Function jsCallback, MessageListenerProxyData *data) {
66
+ Napi::Object obj = Message::NewInstance ({}, data->cMessage );
101
67
102
68
Napi::Function acknowledge = Napi::Function::New (env, &Acknowledge, " Acknowledge" , data);
103
- Napi::Function negativeAcknowledge =
104
- Napi::Function::New (env, &NegativeAcknowledge, " NegativeAcknowledge" , dataCopy);
105
-
106
69
napi_status ackFinalizerStatus =
107
70
napi_wrap (env, acknowledge, data, &FinalizeMessageListenerProxy, NULL , NULL );
108
71
if (ackFinalizerStatus != napi_ok) {
109
- (*data)->Notify ();
110
- delete dataCopy;
111
72
delete data;
112
73
return ;
113
74
}
114
-
115
- napi_status nackFinalizerStatus =
116
- napi_wrap (env, negativeAcknowledge, dataCopy, &FinalizeMessageListenerProxy, NULL , NULL );
117
- if (nackFinalizerStatus != napi_ok) {
118
- (*dataCopy)->Notify ();
119
- delete dataCopy;
120
- return ;
121
- }
122
- jsCallback.Call ({obj, acknowledge, negativeAcknowledge});
75
+ jsCallback.Call ({obj, acknowledge});
123
76
}
124
77
125
78
void MessageListener (pulsar_consumer_t *cConsumer, pulsar_message_t *cMessage, void *ctx) {
126
- Napi::ThreadSafeFunction *listenerCallback = (Napi::ThreadSafeFunction *)ctx;
127
- if (listenerCallback->Acquire () != napi_ok) {
79
+ ListenerCallback *listenerCallback = (ListenerCallback *)ctx;
80
+ if (listenerCallback->callback . Acquire () != napi_ok) {
128
81
return ;
129
82
};
130
- std::shared_ptr<MessageListenerProxyData> data =
131
- std::make_shared<MessageListenerProxyData>(cConsumer, cMessage);
132
- std::shared_ptr<MessageListenerProxyData> *dataPtr = new std::shared_ptr<MessageListenerProxyData>(data);
133
- *dataPtr = data;
134
- listenerCallback->BlockingCall (dataPtr, MessageListenerProxy);
135
- listenerCallback->Release ();
136
-
137
- data->Wait ();
83
+ MessageListenerProxyData *dataPtr =
84
+ new MessageListenerProxyData (listenerCallback->consumerWrapper , cMessage);
85
+ listenerCallback->callback .BlockingCall (dataPtr, MessageListenerProxy);
86
+ listenerCallback->callback .Release ();
138
87
}
139
88
140
89
void FinalizeListenerCallback (Napi::Env env, ListenerCallback *cb, void *) { delete cb; }
141
90
142
- ConsumerConfig::ConsumerConfig (const Napi::Object &consumerConfig)
91
+ ConsumerConfig::ConsumerConfig (const Napi::Object &consumerConfig,
92
+ std::shared_ptr<CConsumerWrapper> consumerWrapper)
143
93
: topic(" " ), subscription(" " ), ackTimeoutMs(0 ), listener(nullptr ) {
144
94
this ->cConsumerConfig = pulsar_consumer_configuration_create ();
145
95
@@ -201,18 +151,21 @@ ConsumerConfig::ConsumerConfig(const Napi::Object &consumerConfig)
201
151
202
152
if (consumerConfig.Has (CFG_LISTENER) && consumerConfig.Get (CFG_LISTENER).IsFunction ()) {
203
153
this ->listener = new ListenerCallback ();
154
+ this ->listener ->consumerWrapper = consumerWrapper;
204
155
Napi::ThreadSafeFunction callback = Napi::ThreadSafeFunction::New (
205
156
consumerConfig.Env (), consumerConfig.Get (CFG_LISTENER).As <Napi::Function>(), " Listener Callback" , 1 ,
206
157
1 , (void *)NULL , FinalizeListenerCallback, listener);
207
158
this ->listener ->callback = std::move (callback);
208
159
pulsar_consumer_configuration_set_message_listener (this ->cConsumerConfig , &MessageListener,
209
- & this ->listener -> callback );
160
+ this ->listener );
210
161
}
211
162
}
212
163
213
164
ConsumerConfig::~ConsumerConfig () {
214
165
pulsar_consumer_configuration_free (this ->cConsumerConfig );
215
- if (this ->listener ) this ->listener ->callback .Release ();
166
+ if (this ->listener ) {
167
+ this ->listener ->callback .Release ();
168
+ }
216
169
}
217
170
218
171
pulsar_consumer_configuration_t *ConsumerConfig::GetCConsumerConfig () { return this ->cConsumerConfig ; }
@@ -226,3 +179,11 @@ ListenerCallback *ConsumerConfig::GetListenerCallback() {
226
179
}
227
180
228
181
int64_t ConsumerConfig::GetAckTimeoutMs () { return this ->ackTimeoutMs ; }
182
+
183
+ CConsumerWrapper::CConsumerWrapper () : cConsumer(nullptr ) {}
184
+
185
+ CConsumerWrapper::~CConsumerWrapper () {
186
+ if (this ->cConsumer ) {
187
+ pulsar_consumer_free (this ->cConsumer );
188
+ }
189
+ }
0 commit comments