pulsar-client 1.11.0-rc.1 → 1.11.0-rc.3

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 CHANGED
@@ -30,6 +30,7 @@ export interface ClientConfig {
30
30
  tlsValidateHostname?: boolean;
31
31
  tlsAllowInsecureConnection?: boolean;
32
32
  statsIntervalInSeconds?: number;
33
+ listenerName?: string;
33
34
  log?: (level: LogLevel, file: string, line: number, message: string) => void;
34
35
  }
35
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pulsar-client",
3
- "version": "1.11.0-rc.1",
3
+ "version": "1.11.0-rc.3",
4
4
  "description": "Pulsar Node.js client",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/src/Client.cc CHANGED
@@ -40,6 +40,7 @@ static const std::string CFG_TLS_VALIDATE_HOSTNAME = "tlsValidateHostname";
40
40
  static const std::string CFG_TLS_ALLOW_INSECURE = "tlsAllowInsecureConnection";
41
41
  static const std::string CFG_STATS_INTERVAL = "statsIntervalInSeconds";
42
42
  static const std::string CFG_LOG = "log";
43
+ static const std::string CFG_LISTENER_NAME = "listenerName";
43
44
 
44
45
  LogCallback *Client::logCallback = nullptr;
45
46
 
@@ -186,6 +187,11 @@ Client::Client(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Client>(info)
186
187
  pulsar_client_configuration_set_stats_interval_in_seconds(cClientConfig.get(), statsIntervalInSeconds);
187
188
  }
188
189
 
190
+ if (clientConfig.Has(CFG_LISTENER_NAME) && clientConfig.Get(CFG_LISTENER_NAME).IsString()) {
191
+ Napi::String listenerName = clientConfig.Get(CFG_LISTENER_NAME).ToString();
192
+ pulsar_client_configuration_set_listener_name(cClientConfig.get(), listenerName.Utf8Value().c_str());
193
+ }
194
+
189
195
  try {
190
196
  this->cClient = std::shared_ptr<pulsar_client_t>(
191
197
  pulsar_client_create(serviceUrl.Utf8Value().c_str(), cClientConfig.get()), pulsar_client_free);
package/src/Reader.cc CHANGED
@@ -60,17 +60,19 @@ struct ReaderListenerProxyData {
60
60
  void ReaderListenerProxy(Napi::Env env, Napi::Function jsCallback, ReaderListenerProxyData *data) {
61
61
  Napi::Object msg = Message::NewInstance({}, data->cMessage);
62
62
  Reader *reader = data->reader;
63
-
64
- Napi::Value ret = jsCallback.Call({msg, reader->Value()});
65
- if (ret.IsPromise()) {
66
- Napi::Promise promise = ret.As<Napi::Promise>();
67
- Napi::Value thenValue = promise.Get("then");
68
- if (thenValue.IsFunction()) {
69
- Napi::Function then = thenValue.As<Napi::Function>();
70
- Napi::Function callback =
71
- Napi::Function::New(env, [data](const Napi::CallbackInfo &info) { data->callback(); });
72
- then.Call(promise, {callback});
73
- return;
63
+ // `reader` might be null in certain cases, segmentation fault might happend without this null check.
64
+ if (reader) {
65
+ Napi::Value ret = jsCallback.Call({msg, reader->Value()});
66
+ if (ret.IsPromise()) {
67
+ Napi::Promise promise = ret.As<Napi::Promise>();
68
+ Napi::Value thenValue = promise.Get("then");
69
+ if (thenValue.IsFunction()) {
70
+ Napi::Function then = thenValue.As<Napi::Function>();
71
+ Napi::Function callback =
72
+ Napi::Function::New(env, [data](const Napi::CallbackInfo &info) { data->callback(); });
73
+ then.Call(promise, {callback});
74
+ return;
75
+ }
74
76
  }
75
77
  }
76
78
  data->callback();
@@ -38,6 +38,13 @@ bindAddress=0.0.0.0
38
38
  # Hostname or IP address the service advertises to the outside world. If not set, the value of InetAddress.getLocalHost().getHostName() is used.
39
39
  advertisedAddress=localhost
40
40
 
41
+ # Used to specify multiple advertised listeners for the broker.
42
+ # The value must format as <listener_name>:pulsar://<host>:<port>,
43
+ # multiple listeners should separate with commas.
44
+ # Do not use this configuration with advertisedAddress and brokerServicePort.
45
+ # The Default value is absent means use advertisedAddress and brokerServicePort.
46
+ advertisedListeners=localhost6650:pulsar://localhost:6650,localhost6651:pulsar+ssl://localhost:6651,localhost8443:pulsar+ssl://localhost:8443
47
+
41
48
  # Name of the cluster to which this broker belongs to
42
49
  clusterName=standalone
43
50
 
@@ -23,15 +23,16 @@ const Pulsar = require('../index');
23
23
  (() => {
24
24
  describe('End To End', () => {
25
25
  test.each([
26
- ['pulsar://localhost:6650'],
27
- ['pulsar+ssl://localhost:6651'],
28
- ['http://localhost:8080'],
29
- ['https://localhost:8443'],
30
- ])('Produce/Consume to %s', async (serviceUrl) => {
26
+ { serviceUrl: 'pulsar://localhost:6650', listenerName: undefined },
27
+ { serviceUrl: 'pulsar+ssl://localhost:6651', listenerName: 'localhost6651' },
28
+ { serviceUrl: 'http://localhost:8080', listenerName: undefined },
29
+ { serviceUrl: 'https://localhost:8443', listenerName: 'localhost8443' },
30
+ ])('Produce/Consume to $serviceUrl', async ({ serviceUrl, listenerName }) => {
31
31
  const client = new Pulsar.Client({
32
32
  serviceUrl,
33
33
  tlsTrustCertsFilePath: `${__dirname}/certificate/server.crt`,
34
34
  operationTimeoutSeconds: 30,
35
+ listenerName,
35
36
  });
36
37
 
37
38
  const topic = 'persistent://public/default/produce-consume';
@@ -130,5 +130,46 @@ const baseUrl = 'http://localhost:8080';
130
130
  await reader.close();
131
131
  await client.close();
132
132
  });
133
+
134
+ test('Reader should not throw segmentation fault when create and close', async () => {
135
+ const NUM_ITS = 1000;
136
+ const its = Array.from({ length: NUM_ITS }, (_, i) => i);
137
+
138
+ const client = new Pulsar.Client({
139
+ serviceUrl: 'pulsar://localhost:6650',
140
+ });
141
+
142
+ const producer = await client.createProducer({
143
+ topic: 'persistent://public/default/my-topic',
144
+ sendTimeoutMs: 30000,
145
+ batchingEnabled: true,
146
+ });
147
+
148
+ // Send messages
149
+ for (let i = 0; i < 10; i += 1) {
150
+ const msg = `my-message-${i}`;
151
+ producer.send({
152
+ data: Buffer.from(msg),
153
+ });
154
+ console.log(`Sent message: ${msg}`);
155
+ }
156
+ await producer.flush();
157
+
158
+ await Promise.all(
159
+ its.map(async () => {
160
+ const reader = await client.createReader({
161
+ topic: 'persistent://public/default/my-topic',
162
+ startMessageId: Pulsar.MessageId.earliest(),
163
+ listener: (message) => {
164
+ console.log(message.getData().toString());
165
+ },
166
+ });
167
+ await reader.close();
168
+ }),
169
+ );
170
+ await producer.close();
171
+ await client.close();
172
+ expect(true).toBe(true);
173
+ });
133
174
  });
134
175
  })();