pulsar-client 1.14.0 → 1.15.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/index.d.ts +19 -0
- package/package.json +4 -1
- package/src/Producer.cc +3 -1
- package/src/Producer.h +5 -0
- package/src/ProducerConfig.cc +48 -0
- package/src/ProducerConfig.h +7 -0
package/index.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ export interface ProducerConfig {
|
|
|
68
68
|
schema?: SchemaInfo;
|
|
69
69
|
accessMode?: ProducerAccessMode;
|
|
70
70
|
batchingType?: ProducerBatchType;
|
|
71
|
+
messageRouter?: MessageRouter;
|
|
72
|
+
batchingMaxAllowedSizeInBytes?: number;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
export class Producer {
|
|
@@ -176,6 +178,23 @@ export class MessageId {
|
|
|
176
178
|
toString(): string;
|
|
177
179
|
}
|
|
178
180
|
|
|
181
|
+
export interface TopicMetadata {
|
|
182
|
+
numPartitions: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* @callback MessageRouter
|
|
187
|
+
* @description When producing messages to a partitioned topic, this router is used to select the
|
|
188
|
+
* target partition for each message. The router only works when the `messageRoutingMode` is set to
|
|
189
|
+
* `CustomPartition`. Please note that `getTopicName()` cannot be called on the `message`, otherwise
|
|
190
|
+
* the behavior will be undefined because the topic is unknown before sending the message.
|
|
191
|
+
* @param message The message to be routed.
|
|
192
|
+
* @param topicMetadata Metadata for the partitioned topic the message is being routed to.
|
|
193
|
+
* @returns {number} The index of the target partition (must be a number between 0 and
|
|
194
|
+
* topicMetadata.numPartitions - 1).
|
|
195
|
+
*/
|
|
196
|
+
export type MessageRouter = (message: Message, topicMetadata: TopicMetadata) => number;
|
|
197
|
+
|
|
179
198
|
export interface SchemaInfo {
|
|
180
199
|
schemaType: SchemaType;
|
|
181
200
|
name?: string;
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulsar-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Pulsar Node.js client",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
+
"resolutions": {
|
|
8
|
+
"minimatch": "^9.0.0"
|
|
9
|
+
},
|
|
7
10
|
"directories": {
|
|
8
11
|
"src": "src",
|
|
9
12
|
"example": "examples"
|
package/src/Producer.cc
CHANGED
|
@@ -73,6 +73,7 @@ Napi::Value Producer::NewInstance(const Napi::CallbackInfo &info, std::shared_pt
|
|
|
73
73
|
auto instanceContext = static_cast<ProducerNewInstanceContext *>(ctx);
|
|
74
74
|
auto deferred = instanceContext->deferred;
|
|
75
75
|
auto cClient = instanceContext->cClient;
|
|
76
|
+
auto producerConfig = instanceContext->producerConfig;
|
|
76
77
|
delete instanceContext;
|
|
77
78
|
|
|
78
79
|
if (result != pulsar_result_Ok) {
|
|
@@ -81,10 +82,11 @@ Napi::Value Producer::NewInstance(const Napi::CallbackInfo &info, std::shared_pt
|
|
|
81
82
|
|
|
82
83
|
std::shared_ptr<pulsar_producer_t> cProducer(rawProducer, pulsar_producer_free);
|
|
83
84
|
|
|
84
|
-
deferred->Resolve([cProducer](const Napi::Env env) {
|
|
85
|
+
deferred->Resolve([cProducer, producerConfig](const Napi::Env env) {
|
|
85
86
|
Napi::Object obj = Producer::constructor.New({});
|
|
86
87
|
Producer *producer = Producer::Unwrap(obj);
|
|
87
88
|
producer->SetCProducer(cProducer);
|
|
89
|
+
producer->producerConfig = producerConfig;
|
|
88
90
|
return obj;
|
|
89
91
|
});
|
|
90
92
|
},
|
package/src/Producer.h
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
#include <napi.h>
|
|
24
24
|
#include <pulsar/c/client.h>
|
|
25
25
|
#include <pulsar/c/producer.h>
|
|
26
|
+
#include <memory>
|
|
27
|
+
#include "ProducerConfig.h"
|
|
26
28
|
|
|
27
29
|
class Producer : public Napi::ObjectWrap<Producer> {
|
|
28
30
|
public:
|
|
@@ -35,6 +37,9 @@ class Producer : public Napi::ObjectWrap<Producer> {
|
|
|
35
37
|
|
|
36
38
|
private:
|
|
37
39
|
std::shared_ptr<pulsar_producer_t> cProducer;
|
|
40
|
+
// Extend the lifetime of the producer config since it's env and router function could be used when sending
|
|
41
|
+
// messages
|
|
42
|
+
std::shared_ptr<ProducerConfig> producerConfig;
|
|
38
43
|
Napi::Value Send(const Napi::CallbackInfo &info);
|
|
39
44
|
Napi::Value Flush(const Napi::CallbackInfo &info);
|
|
40
45
|
Napi::Value Close(const Napi::CallbackInfo &info);
|
package/src/ProducerConfig.cc
CHANGED
|
@@ -18,8 +18,14 @@
|
|
|
18
18
|
*/
|
|
19
19
|
#include "SchemaInfo.h"
|
|
20
20
|
#include "ProducerConfig.h"
|
|
21
|
+
#include "Message.h"
|
|
22
|
+
#include <cstdio>
|
|
21
23
|
#include <map>
|
|
24
|
+
#include "napi-inl.h"
|
|
25
|
+
#include "napi.h"
|
|
22
26
|
#include "pulsar/ProducerConfiguration.h"
|
|
27
|
+
#include "pulsar/c/message.h"
|
|
28
|
+
#include "pulsar/c/message_router.h"
|
|
23
29
|
|
|
24
30
|
static const std::string CFG_TOPIC = "topic";
|
|
25
31
|
static const std::string CFG_PRODUCER_NAME = "producerName";
|
|
@@ -34,6 +40,7 @@ static const std::string CFG_COMPRESS_TYPE = "compressionType";
|
|
|
34
40
|
static const std::string CFG_BATCH_ENABLED = "batchingEnabled";
|
|
35
41
|
static const std::string CFG_BATCH_MAX_DELAY = "batchingMaxPublishDelayMs";
|
|
36
42
|
static const std::string CFG_BATCH_MAX_MSG = "batchingMaxMessages";
|
|
43
|
+
static const std::string CFG_BATCH_MAX_ALLOWED_SIZE_IN_BYTES = "batchingMaxAllowedSizeInBytes";
|
|
37
44
|
static const std::string CFG_SCHEMA = "schema";
|
|
38
45
|
static const std::string CFG_PROPS = "properties";
|
|
39
46
|
static const std::string CFG_PUBLIC_KEY_PATH = "publicKeyPath";
|
|
@@ -42,6 +49,7 @@ static const std::string CFG_CRYPTO_FAILURE_ACTION = "cryptoFailureAction";
|
|
|
42
49
|
static const std::string CFG_CHUNK_ENABLED = "chunkingEnabled";
|
|
43
50
|
static const std::string CFG_ACCESS_MODE = "accessMode";
|
|
44
51
|
static const std::string CFG_BATCHING_TYPE = "batchingType";
|
|
52
|
+
static const std::string CFG_MESSAGE_ROUTER = "messageRouter";
|
|
45
53
|
|
|
46
54
|
struct _pulsar_producer_configuration {
|
|
47
55
|
pulsar::ProducerConfiguration conf;
|
|
@@ -82,6 +90,25 @@ static std::map<std::string, pulsar::ProducerConfiguration::BatchingType> PRODUC
|
|
|
82
90
|
{"KeyBasedBatching", pulsar::ProducerConfiguration::KeyBasedBatching},
|
|
83
91
|
};
|
|
84
92
|
|
|
93
|
+
static int choosePartition(pulsar_message_t* msg, pulsar_topic_metadata_t* metadata, void* ctx) {
|
|
94
|
+
auto router = static_cast<Napi::FunctionReference*>(ctx);
|
|
95
|
+
const auto& env = router->Env();
|
|
96
|
+
auto jsMessage = Message::NewInstance(Napi::Object::New(env),
|
|
97
|
+
std::shared_ptr<pulsar_message_t>(msg, [](pulsar_message_t*) {}));
|
|
98
|
+
int numPartitions = pulsar_topic_metadata_get_num_partitions(metadata);
|
|
99
|
+
|
|
100
|
+
Napi::Object jsTopicMetadata = Napi::Object::New(env);
|
|
101
|
+
jsTopicMetadata.Set("numPartitions", Napi::Number::New(env, numPartitions));
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
return router->Call({jsMessage, jsTopicMetadata}).ToNumber().Int32Value();
|
|
105
|
+
} catch (const Napi::Error& e) {
|
|
106
|
+
// TODO: how to handle the error properly? For now, return an invalid partition to fail the send
|
|
107
|
+
fprintf(stderr, "Error when calling messageRouter: %s\n", e.what());
|
|
108
|
+
return numPartitions;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
85
112
|
ProducerConfig::ProducerConfig(const Napi::Object& producerConfig) : topic("") {
|
|
86
113
|
this->cProducerConfig = std::shared_ptr<pulsar_producer_configuration_t>(
|
|
87
114
|
pulsar_producer_configuration_create(), pulsar_producer_configuration_free);
|
|
@@ -131,8 +158,10 @@ ProducerConfig::ProducerConfig(const Napi::Object& producerConfig) : topic("") {
|
|
|
131
158
|
pulsar_producer_configuration_set_block_if_queue_full(this->cProducerConfig.get(), blockIfQueueFull);
|
|
132
159
|
}
|
|
133
160
|
|
|
161
|
+
bool useCustomPartition = false;
|
|
134
162
|
if (producerConfig.Has(CFG_ROUTING_MODE) && producerConfig.Get(CFG_ROUTING_MODE).IsString()) {
|
|
135
163
|
std::string messageRoutingMode = producerConfig.Get(CFG_ROUTING_MODE).ToString().Utf8Value();
|
|
164
|
+
useCustomPartition = (messageRoutingMode == "CustomPartition");
|
|
136
165
|
if (MESSAGE_ROUTING_MODE.count(messageRoutingMode))
|
|
137
166
|
pulsar_producer_configuration_set_partitions_routing_mode(this->cProducerConfig.get(),
|
|
138
167
|
MESSAGE_ROUTING_MODE.at(messageRoutingMode));
|
|
@@ -173,6 +202,16 @@ ProducerConfig::ProducerConfig(const Napi::Object& producerConfig) : topic("") {
|
|
|
173
202
|
}
|
|
174
203
|
}
|
|
175
204
|
|
|
205
|
+
if (producerConfig.Has(CFG_BATCH_MAX_ALLOWED_SIZE_IN_BYTES) &&
|
|
206
|
+
producerConfig.Get(CFG_BATCH_MAX_ALLOWED_SIZE_IN_BYTES).IsNumber()) {
|
|
207
|
+
int64_t batchingMaxAllowedSizeInBytes =
|
|
208
|
+
producerConfig.Get(CFG_BATCH_MAX_ALLOWED_SIZE_IN_BYTES).ToNumber().Int64Value();
|
|
209
|
+
if (batchingMaxAllowedSizeInBytes > 0) {
|
|
210
|
+
pulsar_producer_configuration_set_batching_max_allowed_size_in_bytes(
|
|
211
|
+
this->cProducerConfig.get(), (unsigned long)batchingMaxAllowedSizeInBytes);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
176
215
|
if (producerConfig.Has(CFG_SCHEMA) && producerConfig.Get(CFG_SCHEMA).IsObject()) {
|
|
177
216
|
SchemaInfo* schemaInfo = new SchemaInfo(producerConfig.Get(CFG_SCHEMA).ToObject());
|
|
178
217
|
schemaInfo->SetProducerSchema(this->cProducerConfig);
|
|
@@ -224,6 +263,15 @@ ProducerConfig::ProducerConfig(const Napi::Object& producerConfig) : topic("") {
|
|
|
224
263
|
if (PRODUCER_BATCHING_TYPE.count(batchingType)) {
|
|
225
264
|
this->cProducerConfig.get()->conf.setBatchingType(PRODUCER_BATCHING_TYPE.at(batchingType));
|
|
226
265
|
}
|
|
266
|
+
|
|
267
|
+
if (useCustomPartition && producerConfig.Has(CFG_MESSAGE_ROUTER)) {
|
|
268
|
+
auto value = producerConfig.Get(CFG_MESSAGE_ROUTER);
|
|
269
|
+
if (value.IsFunction()) {
|
|
270
|
+
messageRouter = Napi::Persistent(value.As<Napi::Function>());
|
|
271
|
+
pulsar_producer_configuration_set_message_router(this->cProducerConfig.get(), choosePartition,
|
|
272
|
+
&messageRouter);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
227
275
|
}
|
|
228
276
|
|
|
229
277
|
ProducerConfig::~ProducerConfig() {}
|
package/src/ProducerConfig.h
CHANGED
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
|
|
23
23
|
#include <napi.h>
|
|
24
24
|
#include <pulsar/c/producer_configuration.h>
|
|
25
|
+
#include <memory>
|
|
26
|
+
|
|
27
|
+
struct MessageRouterContext {
|
|
28
|
+
Napi::FunctionReference messageRouter;
|
|
29
|
+
};
|
|
25
30
|
|
|
26
31
|
class ProducerConfig {
|
|
27
32
|
public:
|
|
@@ -33,6 +38,8 @@ class ProducerConfig {
|
|
|
33
38
|
private:
|
|
34
39
|
std::shared_ptr<pulsar_producer_configuration_t> cProducerConfig;
|
|
35
40
|
std::string topic;
|
|
41
|
+
std::unique_ptr<MessageRouterContext> routerContext;
|
|
42
|
+
Napi::FunctionReference messageRouter;
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
#endif
|