pulsar-client 1.6.2-rc.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -7
- package/binding.gyp +23 -5
- package/docker-tests.sh +4 -3
- package/index.d.ts +5 -4
- package/package.json +4 -10
- package/pulsar-test-service-start.sh +1 -1
- package/pulsar-version.txt +1 -1
- package/run-unit-tests.sh +1 -1
- package/src/Client.cc +84 -58
- package/src/Client.h +6 -4
- package/src/Consumer.cc +260 -231
- package/src/Consumer.h +9 -9
- package/src/ConsumerConfig.cc +33 -32
- package/src/ConsumerConfig.h +5 -6
- package/src/Message.cc +26 -29
- package/src/Message.h +4 -4
- package/src/MessageId.cc +19 -22
- package/src/MessageId.h +5 -6
- package/src/MessageListener.h +3 -8
- package/src/Producer.cc +116 -133
- package/src/Producer.h +3 -3
- package/src/ProducerConfig.cc +33 -22
- package/src/ProducerConfig.h +2 -2
- package/src/Reader.cc +98 -129
- package/src/Reader.h +3 -3
- package/src/ReaderConfig.cc +14 -20
- package/src/ReaderConfig.h +5 -6
- package/src/ReaderListener.h +2 -7
- package/src/SchemaInfo.cc +78 -0
- package/src/SchemaInfo.h +41 -0
- package/src/ThreadSafeDeferred.cc +98 -0
- package/src/ThreadSafeDeferred.h +85 -0
- package/tests/consumer.test.js +2 -2
- package/tests/end_to_end.test.js +2 -2
- package/tests/producer.test.js +2 -2
package/src/Reader.cc
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
#include "Message.h"
|
|
21
21
|
#include "Reader.h"
|
|
22
22
|
#include "ReaderConfig.h"
|
|
23
|
+
#include "ThreadSafeDeferred.h"
|
|
23
24
|
#include <pulsar/c/result.h>
|
|
24
25
|
#include <pulsar/c/reader.h>
|
|
25
26
|
#include <atomic>
|
|
@@ -43,10 +44,11 @@ void Reader::Init(Napi::Env env, Napi::Object exports) {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
struct ReaderListenerProxyData {
|
|
46
|
-
pulsar_message_t
|
|
47
|
+
std::shared_ptr<pulsar_message_t> cMessage;
|
|
47
48
|
Reader *reader;
|
|
48
49
|
|
|
49
|
-
ReaderListenerProxyData(pulsar_message_t
|
|
50
|
+
ReaderListenerProxyData(std::shared_ptr<pulsar_message_t> cMessage, Reader *reader)
|
|
51
|
+
: cMessage(cMessage), reader(reader) {}
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
void ReaderListenerProxy(Napi::Env env, Napi::Function jsCallback, ReaderListenerProxyData *data) {
|
|
@@ -57,7 +59,8 @@ void ReaderListenerProxy(Napi::Env env, Napi::Function jsCallback, ReaderListene
|
|
|
57
59
|
jsCallback.Call({msg, reader->Value()});
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
void ReaderListener(pulsar_reader_t *
|
|
62
|
+
void ReaderListener(pulsar_reader_t *rawReader, pulsar_message_t *rawMessage, void *ctx) {
|
|
63
|
+
std::shared_ptr<pulsar_message_t> cMessage(rawMessage, pulsar_message_free);
|
|
61
64
|
ReaderListenerCallback *readerListenerCallback = (ReaderListenerCallback *)ctx;
|
|
62
65
|
Reader *reader = (Reader *)readerListenerCallback->reader;
|
|
63
66
|
if (readerListenerCallback->callback.Acquire() != napi_ok) {
|
|
@@ -68,101 +71,85 @@ void ReaderListener(pulsar_reader_t *cReader, pulsar_message_t *cMessage, void *
|
|
|
68
71
|
readerListenerCallback->callback.Release();
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
void Reader::SetCReader(std::shared_ptr<
|
|
74
|
+
void Reader::SetCReader(std::shared_ptr<pulsar_reader_t> cReader) { this->cReader = cReader; }
|
|
72
75
|
void Reader::SetListenerCallback(ReaderListenerCallback *listener) {
|
|
73
|
-
if (listener) {
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
if (this->listener != nullptr) {
|
|
77
|
+
// It is only safe to set the listener once for the lifecycle of the Reader
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
if (listener != nullptr) {
|
|
79
82
|
listener->reader = this;
|
|
83
|
+
// If a reader listener is set, the Reader instance is kept alive even if it goes out of scope in JS code.
|
|
84
|
+
this->Ref();
|
|
85
|
+
this->listener = listener;
|
|
80
86
|
}
|
|
81
|
-
|
|
82
|
-
this->listener = listener;
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
Reader::Reader(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Reader>(info), listener(nullptr) {}
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
SetError(msg);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (this->readerConfig->GetCStartMessageId() == nullptr) {
|
|
106
|
-
std::string msg(
|
|
107
|
-
"StartMessageId is required and must be specified as a MessageId object when creating reader");
|
|
108
|
-
SetError(msg);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
pulsar_client_create_reader_async(this->cClient, topic.c_str(), this->readerConfig->GetCStartMessageId(),
|
|
113
|
-
this->readerConfig->GetCReaderConfig(),
|
|
114
|
-
&ReaderNewInstanceWorker::createReaderCallback, (void *)this);
|
|
115
|
-
|
|
116
|
-
while (!done) {
|
|
117
|
-
std::this_thread::yield();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
void OnOK() {
|
|
121
|
-
Napi::Object obj = Reader::constructor.New({});
|
|
122
|
-
Reader *reader = Reader::Unwrap(obj);
|
|
123
|
-
reader->SetCReader(this->readerWrapper);
|
|
124
|
-
reader->SetListenerCallback(this->listener);
|
|
125
|
-
this->deferred.Resolve(obj);
|
|
126
|
-
}
|
|
127
|
-
void OnError(const Napi::Error &e) { this->deferred.Reject(Napi::Error::New(Env(), e.Message()).Value()); }
|
|
91
|
+
struct ReaderNewInstanceContext {
|
|
92
|
+
ReaderNewInstanceContext(std::shared_ptr<ThreadSafeDeferred> deferred,
|
|
93
|
+
std::shared_ptr<pulsar_client_t> cClient,
|
|
94
|
+
std::shared_ptr<ReaderConfig> readerConfig)
|
|
95
|
+
: deferred(deferred), cClient(cClient), readerConfig(readerConfig){};
|
|
96
|
+
std::shared_ptr<ThreadSafeDeferred> deferred;
|
|
97
|
+
std::shared_ptr<pulsar_client_t> cClient;
|
|
98
|
+
std::shared_ptr<ReaderConfig> readerConfig;
|
|
99
|
+
|
|
100
|
+
static void createReaderCallback(pulsar_result result, pulsar_reader_t *rawReader, void *ctx) {
|
|
101
|
+
auto instanceContext = static_cast<ReaderNewInstanceContext *>(ctx);
|
|
102
|
+
auto deferred = instanceContext->deferred;
|
|
103
|
+
auto cClient = instanceContext->cClient;
|
|
104
|
+
auto readerConfig = instanceContext->readerConfig;
|
|
105
|
+
delete instanceContext;
|
|
128
106
|
|
|
129
|
-
private:
|
|
130
|
-
Napi::Promise::Deferred deferred;
|
|
131
|
-
pulsar_client_t *cClient;
|
|
132
|
-
pulsar_reader_t *cReader;
|
|
133
|
-
ReaderConfig *readerConfig;
|
|
134
|
-
ReaderListenerCallback *listener;
|
|
135
|
-
std::shared_ptr<CReaderWrapper> readerWrapper;
|
|
136
|
-
std::atomic<bool> done;
|
|
137
|
-
static void createReaderCallback(pulsar_result result, pulsar_reader_t *reader, void *ctx) {
|
|
138
|
-
ReaderNewInstanceWorker *worker = (ReaderNewInstanceWorker *)ctx;
|
|
139
107
|
if (result != pulsar_result_Ok) {
|
|
140
|
-
|
|
141
|
-
} else {
|
|
142
|
-
worker->readerWrapper->cReader = reader;
|
|
143
|
-
worker->listener = worker->readerConfig->GetListenerCallback();
|
|
108
|
+
return deferred->Reject(std::string("Failed to create reader: ") + pulsar_result_str(result));
|
|
144
109
|
}
|
|
145
110
|
|
|
146
|
-
|
|
147
|
-
|
|
111
|
+
auto cReader = std::shared_ptr<pulsar_reader_t>(rawReader, pulsar_reader_free);
|
|
112
|
+
|
|
113
|
+
deferred->Resolve([cReader, readerConfig](const Napi::Env env) {
|
|
114
|
+
Napi::Object obj = Reader::constructor.New({});
|
|
115
|
+
Reader *reader = Reader::Unwrap(obj);
|
|
116
|
+
reader->SetCReader(cReader);
|
|
117
|
+
reader->SetListenerCallback(readerConfig->GetListenerCallback());
|
|
118
|
+
return obj;
|
|
119
|
+
});
|
|
148
120
|
}
|
|
149
121
|
};
|
|
150
122
|
|
|
151
|
-
Napi::Value Reader::NewInstance(const Napi::CallbackInfo &info, pulsar_client_t
|
|
152
|
-
|
|
123
|
+
Napi::Value Reader::NewInstance(const Napi::CallbackInfo &info, std::shared_ptr<pulsar_client_t> cClient) {
|
|
124
|
+
auto deferred = ThreadSafeDeferred::New(info.Env());
|
|
153
125
|
Napi::Object config = info[0].As<Napi::Object>();
|
|
154
126
|
|
|
155
|
-
|
|
127
|
+
auto readerConfig = std::make_shared<ReaderConfig>(config, &ReaderListener);
|
|
156
128
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
129
|
+
const std::string &topic = readerConfig->GetTopic();
|
|
130
|
+
if (topic.empty()) {
|
|
131
|
+
deferred->Reject(std::string("Topic is required and must be specified as a string when creating reader"));
|
|
132
|
+
return deferred->Promise();
|
|
133
|
+
}
|
|
134
|
+
if (readerConfig->GetCStartMessageId().get() == nullptr) {
|
|
135
|
+
deferred->Reject(std::string(
|
|
136
|
+
"StartMessageId is required and must be specified as a MessageId object when creating reader"));
|
|
137
|
+
return deferred->Promise();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
auto ctx = new ReaderNewInstanceContext(deferred, cClient, readerConfig);
|
|
141
|
+
|
|
142
|
+
pulsar_client_create_reader_async(cClient.get(), topic.c_str(), readerConfig->GetCStartMessageId().get(),
|
|
143
|
+
readerConfig->GetCReaderConfig().get(),
|
|
144
|
+
&ReaderNewInstanceContext::createReaderCallback, ctx);
|
|
145
|
+
|
|
146
|
+
return deferred->Promise();
|
|
161
147
|
}
|
|
162
148
|
|
|
149
|
+
// We still need a read worker because the c api is missing the equivalent async definition
|
|
163
150
|
class ReaderReadNextWorker : public Napi::AsyncWorker {
|
|
164
151
|
public:
|
|
165
|
-
ReaderReadNextWorker(const Napi::Promise::Deferred &deferred, pulsar_reader_t
|
|
152
|
+
ReaderReadNextWorker(const Napi::Promise::Deferred &deferred, std::shared_ptr<pulsar_reader_t> cReader,
|
|
166
153
|
int64_t timeout = -1)
|
|
167
154
|
: AsyncWorker(Napi::Function::New(deferred.Promise().Env(), [](const Napi::CallbackInfo &info) {})),
|
|
168
155
|
deferred(deferred),
|
|
@@ -171,14 +158,16 @@ class ReaderReadNextWorker : public Napi::AsyncWorker {
|
|
|
171
158
|
~ReaderReadNextWorker() {}
|
|
172
159
|
void Execute() {
|
|
173
160
|
pulsar_result result;
|
|
161
|
+
pulsar_message_t *rawMessage;
|
|
174
162
|
if (timeout > 0) {
|
|
175
|
-
result = pulsar_reader_read_next_with_timeout(this->cReader, &
|
|
163
|
+
result = pulsar_reader_read_next_with_timeout(this->cReader.get(), &rawMessage, timeout);
|
|
176
164
|
} else {
|
|
177
|
-
result = pulsar_reader_read_next(this->cReader, &
|
|
165
|
+
result = pulsar_reader_read_next(this->cReader.get(), &rawMessage);
|
|
178
166
|
}
|
|
179
167
|
if (result != pulsar_result_Ok) {
|
|
180
168
|
SetError(std::string("Failed to received message ") + pulsar_result_str(result));
|
|
181
169
|
}
|
|
170
|
+
this->cMessage = std::shared_ptr<pulsar_message_t>(rawMessage, pulsar_message_free);
|
|
182
171
|
}
|
|
183
172
|
void OnOK() {
|
|
184
173
|
Napi::Object obj = Message::NewInstance({}, this->cMessage);
|
|
@@ -188,20 +177,19 @@ class ReaderReadNextWorker : public Napi::AsyncWorker {
|
|
|
188
177
|
|
|
189
178
|
private:
|
|
190
179
|
Napi::Promise::Deferred deferred;
|
|
191
|
-
pulsar_reader_t
|
|
192
|
-
pulsar_message_t
|
|
180
|
+
std::shared_ptr<pulsar_reader_t> cReader;
|
|
181
|
+
std::shared_ptr<pulsar_message_t> cMessage;
|
|
193
182
|
int64_t timeout;
|
|
194
183
|
};
|
|
195
184
|
|
|
196
185
|
Napi::Value Reader::ReadNext(const Napi::CallbackInfo &info) {
|
|
197
186
|
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(info.Env());
|
|
198
187
|
if (info[0].IsUndefined()) {
|
|
199
|
-
ReaderReadNextWorker *wk = new ReaderReadNextWorker(deferred, this->
|
|
188
|
+
ReaderReadNextWorker *wk = new ReaderReadNextWorker(deferred, this->cReader);
|
|
200
189
|
wk->Queue();
|
|
201
190
|
} else {
|
|
202
191
|
Napi::Number timeout = info[0].As<Napi::Object>().ToNumber();
|
|
203
|
-
ReaderReadNextWorker *wk =
|
|
204
|
-
new ReaderReadNextWorker(deferred, this->wrapper->cReader, timeout.Int64Value());
|
|
192
|
+
ReaderReadNextWorker *wk = new ReaderReadNextWorker(deferred, this->cReader, timeout.Int64Value());
|
|
205
193
|
wk->Queue();
|
|
206
194
|
}
|
|
207
195
|
return deferred.Promise();
|
|
@@ -209,7 +197,7 @@ Napi::Value Reader::ReadNext(const Napi::CallbackInfo &info) {
|
|
|
209
197
|
|
|
210
198
|
Napi::Value Reader::HasNext(const Napi::CallbackInfo &info) {
|
|
211
199
|
int value = 0;
|
|
212
|
-
pulsar_result result = pulsar_reader_has_message_available(this->
|
|
200
|
+
pulsar_result result = pulsar_reader_has_message_available(this->cReader.get(), &value);
|
|
213
201
|
if (result != pulsar_result_Ok) {
|
|
214
202
|
Napi::Error::New(info.Env(), "Failed to check if next message is available").ThrowAsJavaScriptException();
|
|
215
203
|
return Napi::Boolean::New(info.Env(), false);
|
|
@@ -222,57 +210,38 @@ Napi::Value Reader::HasNext(const Napi::CallbackInfo &info) {
|
|
|
222
210
|
|
|
223
211
|
Napi::Value Reader::IsConnected(const Napi::CallbackInfo &info) {
|
|
224
212
|
Napi::Env env = info.Env();
|
|
225
|
-
return Napi::Boolean::New(env, pulsar_reader_is_connected(this->
|
|
213
|
+
return Napi::Boolean::New(env, pulsar_reader_is_connected(this->cReader.get()));
|
|
226
214
|
}
|
|
227
215
|
|
|
228
|
-
class ReaderCloseWorker : public Napi::AsyncWorker {
|
|
229
|
-
public:
|
|
230
|
-
ReaderCloseWorker(const Napi::Promise::Deferred &deferred, pulsar_reader_t *cReader, Reader *reader)
|
|
231
|
-
: AsyncWorker(Napi::Function::New(deferred.Promise().Env(), [](const Napi::CallbackInfo &info) {})),
|
|
232
|
-
deferred(deferred),
|
|
233
|
-
cReader(cReader),
|
|
234
|
-
reader(reader) {}
|
|
235
|
-
~ReaderCloseWorker() {}
|
|
236
|
-
void Execute() {
|
|
237
|
-
pulsar_result result = pulsar_reader_close(this->cReader);
|
|
238
|
-
if (result != pulsar_result_Ok) SetError(pulsar_result_str(result));
|
|
239
|
-
}
|
|
240
|
-
void OnOK() {
|
|
241
|
-
this->reader->Cleanup();
|
|
242
|
-
this->deferred.Resolve(Env().Null());
|
|
243
|
-
}
|
|
244
|
-
void OnError(const Napi::Error &e) {
|
|
245
|
-
this->deferred.Reject(
|
|
246
|
-
Napi::Error::New(Env(), std::string("Failed to close reader: ") + e.Message()).Value());
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
private:
|
|
250
|
-
Napi::Promise::Deferred deferred;
|
|
251
|
-
pulsar_reader_t *cReader;
|
|
252
|
-
Reader *reader;
|
|
253
|
-
};
|
|
254
|
-
|
|
255
216
|
Napi::Value Reader::Close(const Napi::CallbackInfo &info) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
217
|
+
auto deferred = ThreadSafeDeferred::New(Env());
|
|
218
|
+
auto ctx = new ExtDeferredContext(deferred);
|
|
219
|
+
this->Cleanup();
|
|
220
|
+
|
|
221
|
+
pulsar_reader_close_async(
|
|
222
|
+
this->cReader.get(),
|
|
223
|
+
[](pulsar_result result, void *ctx) {
|
|
224
|
+
auto deferredContext = static_cast<ExtDeferredContext *>(ctx);
|
|
225
|
+
auto deferred = deferredContext->deferred;
|
|
226
|
+
delete deferredContext;
|
|
227
|
+
|
|
228
|
+
if (result != pulsar_result_Ok) {
|
|
229
|
+
deferred->Reject(std::string("Failed to close reader: ") + pulsar_result_str(result));
|
|
230
|
+
} else {
|
|
231
|
+
deferred->Resolve(THREADSAFE_DEFERRED_RESOLVER(env.Null()));
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
ctx);
|
|
235
|
+
|
|
236
|
+
return deferred->Promise();
|
|
260
237
|
}
|
|
261
238
|
|
|
262
239
|
void Reader::Cleanup() {
|
|
263
|
-
if (this->listener) {
|
|
264
|
-
this->
|
|
240
|
+
if (this->listener != nullptr) {
|
|
241
|
+
this->listener->callback.Release();
|
|
242
|
+
this->Unref();
|
|
243
|
+
this->listener = nullptr;
|
|
265
244
|
}
|
|
266
245
|
}
|
|
267
246
|
|
|
268
|
-
|
|
269
|
-
this->Unref();
|
|
270
|
-
this->listener->callback.Release();
|
|
271
|
-
this->listener = nullptr;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
Reader::~Reader() {
|
|
275
|
-
if (this->listener) {
|
|
276
|
-
this->CleanupListener();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
247
|
+
Reader::~Reader() { this->Cleanup(); }
|
package/src/Reader.h
CHANGED
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
class Reader : public Napi::ObjectWrap<Reader> {
|
|
28
28
|
public:
|
|
29
29
|
static void Init(Napi::Env env, Napi::Object exports);
|
|
30
|
-
static Napi::Value NewInstance(const Napi::CallbackInfo &info, pulsar_client_t
|
|
30
|
+
static Napi::Value NewInstance(const Napi::CallbackInfo &info, std::shared_ptr<pulsar_client_t> cClient);
|
|
31
31
|
static Napi::FunctionReference constructor;
|
|
32
32
|
Reader(const Napi::CallbackInfo &info);
|
|
33
33
|
~Reader();
|
|
34
|
-
void SetCReader(std::shared_ptr<
|
|
34
|
+
void SetCReader(std::shared_ptr<pulsar_reader_t> cReader);
|
|
35
35
|
void SetListenerCallback(ReaderListenerCallback *listener);
|
|
36
36
|
void Cleanup();
|
|
37
37
|
|
|
38
38
|
private:
|
|
39
|
-
std::shared_ptr<
|
|
39
|
+
std::shared_ptr<pulsar_reader_t> cReader;
|
|
40
40
|
ReaderListenerCallback *listener;
|
|
41
41
|
|
|
42
42
|
Napi::Value ReadNext(const Napi::CallbackInfo &info);
|
package/src/ReaderConfig.cc
CHANGED
|
@@ -31,10 +31,10 @@ static const std::string CFG_LISTENER = "listener";
|
|
|
31
31
|
|
|
32
32
|
void FinalizeListenerCallback(Napi::Env env, ReaderListenerCallback *cb, void *) { delete cb; }
|
|
33
33
|
|
|
34
|
-
ReaderConfig::ReaderConfig(const Napi::Object &readerConfig,
|
|
35
|
-
pulsar_reader_listener readerListener)
|
|
34
|
+
ReaderConfig::ReaderConfig(const Napi::Object &readerConfig, pulsar_reader_listener readerListener)
|
|
36
35
|
: topic(""), cStartMessageId(NULL), listener(nullptr) {
|
|
37
|
-
this->cReaderConfig = pulsar_reader_configuration_create()
|
|
36
|
+
this->cReaderConfig = std::shared_ptr<pulsar_reader_configuration_t>(pulsar_reader_configuration_create(),
|
|
37
|
+
pulsar_reader_configuration_free);
|
|
38
38
|
|
|
39
39
|
if (readerConfig.Has(CFG_TOPIC) && readerConfig.Get(CFG_TOPIC).IsString()) {
|
|
40
40
|
this->topic = readerConfig.Get(CFG_TOPIC).ToString().Utf8Value();
|
|
@@ -48,14 +48,14 @@ ReaderConfig::ReaderConfig(const Napi::Object &readerConfig, std::shared_ptr<CRe
|
|
|
48
48
|
if (readerConfig.Has(CFG_RECV_QUEUE) && readerConfig.Get(CFG_RECV_QUEUE).IsNumber()) {
|
|
49
49
|
int32_t receiverQueueSize = readerConfig.Get(CFG_RECV_QUEUE).ToNumber().Int32Value();
|
|
50
50
|
if (receiverQueueSize >= 0) {
|
|
51
|
-
pulsar_reader_configuration_set_receiver_queue_size(this->cReaderConfig, receiverQueueSize);
|
|
51
|
+
pulsar_reader_configuration_set_receiver_queue_size(this->cReaderConfig.get(), receiverQueueSize);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (readerConfig.Has(CFG_READER_NAME) && readerConfig.Get(CFG_READER_NAME).IsString()) {
|
|
56
56
|
std::string readerName = readerConfig.Get(CFG_READER_NAME).ToString().Utf8Value();
|
|
57
57
|
if (!readerName.empty())
|
|
58
|
-
pulsar_reader_configuration_set_reader_name(this->cReaderConfig, readerName.c_str());
|
|
58
|
+
pulsar_reader_configuration_set_reader_name(this->cReaderConfig.get(), readerName.c_str());
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
if (readerConfig.Has(CFG_SUBSCRIPTION_ROLE_PREFIX) &&
|
|
@@ -63,13 +63,13 @@ ReaderConfig::ReaderConfig(const Napi::Object &readerConfig, std::shared_ptr<CRe
|
|
|
63
63
|
std::string subscriptionRolePrefix =
|
|
64
64
|
readerConfig.Get(CFG_SUBSCRIPTION_ROLE_PREFIX).ToString().Utf8Value();
|
|
65
65
|
if (!subscriptionRolePrefix.empty())
|
|
66
|
-
pulsar_reader_configuration_set_reader_name(this->cReaderConfig, subscriptionRolePrefix.c_str());
|
|
66
|
+
pulsar_reader_configuration_set_reader_name(this->cReaderConfig.get(), subscriptionRolePrefix.c_str());
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
if (readerConfig.Has(CFG_READ_COMPACTED) && readerConfig.Get(CFG_READ_COMPACTED).IsBoolean()) {
|
|
70
70
|
bool readCompacted = readerConfig.Get(CFG_READ_COMPACTED).ToBoolean();
|
|
71
71
|
if (readCompacted) {
|
|
72
|
-
pulsar_reader_configuration_set_read_compacted(this->cReaderConfig, 1);
|
|
72
|
+
pulsar_reader_configuration_set_read_compacted(this->cReaderConfig.get(), 1);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -79,33 +79,27 @@ ReaderConfig::ReaderConfig(const Napi::Object &readerConfig, std::shared_ptr<CRe
|
|
|
79
79
|
readerConfig.Env(), readerConfig.Get(CFG_LISTENER).As<Napi::Function>(), "Reader Listener Callback",
|
|
80
80
|
1, 1, (void *)NULL, FinalizeListenerCallback, listener);
|
|
81
81
|
this->listener->callback = std::move(callback);
|
|
82
|
-
pulsar_reader_configuration_set_reader_listener(this->cReaderConfig, readerListener,
|
|
82
|
+
pulsar_reader_configuration_set_reader_listener(this->cReaderConfig.get(), readerListener,
|
|
83
|
+
this->listener);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
ReaderConfig::~ReaderConfig() {
|
|
87
|
-
|
|
88
|
-
if (this->listener) {
|
|
88
|
+
if (this->listener != nullptr) {
|
|
89
89
|
this->listener->callback.Release();
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
pulsar_reader_configuration_t
|
|
93
|
+
std::shared_ptr<pulsar_reader_configuration_t> ReaderConfig::GetCReaderConfig() {
|
|
94
|
+
return this->cReaderConfig;
|
|
95
|
+
}
|
|
94
96
|
|
|
95
97
|
std::string ReaderConfig::GetTopic() { return this->topic; }
|
|
96
98
|
|
|
97
|
-
pulsar_message_id_t
|
|
99
|
+
std::shared_ptr<pulsar_message_id_t> ReaderConfig::GetCStartMessageId() { return this->cStartMessageId; }
|
|
98
100
|
|
|
99
101
|
ReaderListenerCallback *ReaderConfig::GetListenerCallback() {
|
|
100
102
|
ReaderListenerCallback *cb = this->listener;
|
|
101
103
|
this->listener = nullptr;
|
|
102
104
|
return cb;
|
|
103
105
|
}
|
|
104
|
-
|
|
105
|
-
CReaderWrapper::CReaderWrapper() : cReader(nullptr) {}
|
|
106
|
-
|
|
107
|
-
CReaderWrapper::~CReaderWrapper() {
|
|
108
|
-
if (this->cReader) {
|
|
109
|
-
pulsar_reader_free(this->cReader);
|
|
110
|
-
}
|
|
111
|
-
}
|
package/src/ReaderConfig.h
CHANGED
|
@@ -28,18 +28,17 @@
|
|
|
28
28
|
|
|
29
29
|
class ReaderConfig {
|
|
30
30
|
public:
|
|
31
|
-
ReaderConfig(const Napi::Object &readerConfig,
|
|
32
|
-
pulsar_reader_listener readerListener);
|
|
31
|
+
ReaderConfig(const Napi::Object &readerConfig, pulsar_reader_listener readerListener);
|
|
33
32
|
~ReaderConfig();
|
|
34
|
-
pulsar_reader_configuration_t
|
|
35
|
-
pulsar_message_id_t
|
|
33
|
+
std::shared_ptr<pulsar_reader_configuration_t> GetCReaderConfig();
|
|
34
|
+
std::shared_ptr<pulsar_message_id_t> GetCStartMessageId();
|
|
36
35
|
std::string GetTopic();
|
|
37
36
|
ReaderListenerCallback *GetListenerCallback();
|
|
38
37
|
|
|
39
38
|
private:
|
|
40
39
|
std::string topic;
|
|
41
|
-
pulsar_message_id_t
|
|
42
|
-
pulsar_reader_configuration_t
|
|
40
|
+
std::shared_ptr<pulsar_message_id_t> cStartMessageId;
|
|
41
|
+
std::shared_ptr<pulsar_reader_configuration_t> cReaderConfig;
|
|
43
42
|
ReaderListenerCallback *listener;
|
|
44
43
|
};
|
|
45
44
|
|
package/src/ReaderListener.h
CHANGED
|
@@ -21,19 +21,14 @@
|
|
|
21
21
|
#define READER_LISTENER_H
|
|
22
22
|
|
|
23
23
|
#include <napi.h>
|
|
24
|
-
#include <pulsar/c/client.h>
|
|
25
|
-
|
|
26
|
-
struct CReaderWrapper {
|
|
27
|
-
pulsar_reader_t *cReader;
|
|
28
|
-
CReaderWrapper();
|
|
29
|
-
~CReaderWrapper();
|
|
30
|
-
};
|
|
31
24
|
|
|
32
25
|
struct ReaderListenerCallback {
|
|
33
26
|
Napi::ThreadSafeFunction callback;
|
|
34
27
|
|
|
35
28
|
// Using reader as void* since the ReaderListenerCallback is shared between Config and Reader.
|
|
36
29
|
void *reader;
|
|
30
|
+
|
|
31
|
+
ReaderListenerCallback() : reader(nullptr) {}
|
|
37
32
|
};
|
|
38
33
|
|
|
39
34
|
#endif
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
#include "SchemaInfo.h"
|
|
20
|
+
#include <map>
|
|
21
|
+
|
|
22
|
+
static const std::string CFG_SCHEMA_TYPE = "schemaType";
|
|
23
|
+
static const std::string CFG_NAME = "name";
|
|
24
|
+
static const std::string CFG_SCHEMA = "schema";
|
|
25
|
+
static const std::string CFG_PROPS = "properties";
|
|
26
|
+
|
|
27
|
+
static const std::map<std::string, pulsar_schema_type> SCHEMA_TYPE = {{"None", pulsar_None},
|
|
28
|
+
{"String", pulsar_String},
|
|
29
|
+
{"Json", pulsar_Json},
|
|
30
|
+
{"Protobuf", pulsar_Protobuf},
|
|
31
|
+
{"Avro", pulsar_Avro},
|
|
32
|
+
{"Boolean", pulsar_Boolean},
|
|
33
|
+
{"Int8", pulsar_Int8},
|
|
34
|
+
{"Int16", pulsar_Int16},
|
|
35
|
+
{"Int32", pulsar_Int32},
|
|
36
|
+
{"Int64", pulsar_Int64},
|
|
37
|
+
{"Float32", pulsar_Float32},
|
|
38
|
+
{"Float64", pulsar_Float64},
|
|
39
|
+
{"KeyValue", pulsar_KeyValue},
|
|
40
|
+
{"Bytes", pulsar_Bytes},
|
|
41
|
+
{"AutoConsume", pulsar_AutoConsume},
|
|
42
|
+
{"AutoPublish", pulsar_AutoPublish}};
|
|
43
|
+
|
|
44
|
+
SchemaInfo::SchemaInfo(const Napi::Object &schemaInfo) : cSchemaType(pulsar_Bytes), name("BYTES"), schema() {
|
|
45
|
+
this->cProperties = pulsar_string_map_create();
|
|
46
|
+
if (schemaInfo.Has(CFG_SCHEMA_TYPE) && schemaInfo.Get(CFG_SCHEMA_TYPE).IsString()) {
|
|
47
|
+
this->name = schemaInfo.Get(CFG_SCHEMA_TYPE).ToString().Utf8Value();
|
|
48
|
+
this->cSchemaType = SCHEMA_TYPE.at(schemaInfo.Get(CFG_SCHEMA_TYPE).ToString().Utf8Value());
|
|
49
|
+
}
|
|
50
|
+
if (schemaInfo.Has(CFG_NAME) && schemaInfo.Get(CFG_NAME).IsString()) {
|
|
51
|
+
this->name = schemaInfo.Get(CFG_NAME).ToString().Utf8Value();
|
|
52
|
+
}
|
|
53
|
+
if (schemaInfo.Has(CFG_SCHEMA) && schemaInfo.Get(CFG_SCHEMA).IsString()) {
|
|
54
|
+
this->schema = schemaInfo.Get(CFG_SCHEMA).ToString().Utf8Value();
|
|
55
|
+
}
|
|
56
|
+
if (schemaInfo.Has(CFG_PROPS) && schemaInfo.Get(CFG_PROPS).IsObject()) {
|
|
57
|
+
Napi::Object propObj = schemaInfo.Get(CFG_PROPS).ToObject();
|
|
58
|
+
Napi::Array arr = propObj.GetPropertyNames();
|
|
59
|
+
int size = arr.Length();
|
|
60
|
+
for (int i = 0; i < size; i++) {
|
|
61
|
+
Napi::String key = arr.Get(i).ToString();
|
|
62
|
+
Napi::String value = propObj.Get(key).ToString();
|
|
63
|
+
pulsar_string_map_put(this->cProperties, key.Utf8Value().c_str(), value.Utf8Value().c_str());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void SchemaInfo::SetProducerSchema(std::shared_ptr<pulsar_producer_configuration_t> cProducerConfiguration) {
|
|
69
|
+
pulsar_producer_configuration_set_schema_info(cProducerConfiguration.get(), this->cSchemaType,
|
|
70
|
+
this->name.c_str(), this->schema.c_str(), this->cProperties);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void SchemaInfo::SetConsumerSchema(std::shared_ptr<pulsar_consumer_configuration_t> cConsumerConfiguration) {
|
|
74
|
+
pulsar_consumer_configuration_set_schema_info(cConsumerConfiguration.get(), this->cSchemaType,
|
|
75
|
+
this->name.c_str(), this->schema.c_str(), this->cProperties);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
SchemaInfo::~SchemaInfo() { pulsar_string_map_free(this->cProperties); }
|
package/src/SchemaInfo.h
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#ifndef SCHEMA_INFO_H
|
|
21
|
+
#define SCHEMA_INFO_H
|
|
22
|
+
|
|
23
|
+
#include <napi.h>
|
|
24
|
+
#include <pulsar/c/producer_configuration.h>
|
|
25
|
+
#include <pulsar/c/consumer_configuration.h>
|
|
26
|
+
|
|
27
|
+
class SchemaInfo {
|
|
28
|
+
public:
|
|
29
|
+
SchemaInfo(const Napi::Object &schemaInfo);
|
|
30
|
+
~SchemaInfo();
|
|
31
|
+
void SetProducerSchema(std::shared_ptr<pulsar_producer_configuration_t> cProducerConfiguration);
|
|
32
|
+
void SetConsumerSchema(std::shared_ptr<pulsar_consumer_configuration_t> cConsumerConfiguration);
|
|
33
|
+
|
|
34
|
+
private:
|
|
35
|
+
pulsar_schema_type cSchemaType;
|
|
36
|
+
std::string name;
|
|
37
|
+
std::string schema;
|
|
38
|
+
pulsar_string_map_t *cProperties;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
#endif
|