gperinazzo commented on issue #62: Listening for messages
URL: 
https://github.com/apache/pulsar-client-node/issues/62#issuecomment-612976617
 
 
   @yosiat I'm seeing a crash if a client with listener is closed twice after 
your pull request:
   ```js
   const Pulsar = require('./index.js');
   
   const delay = (time) => new Promise(resolve => setTimeout(resolve, time));
   
   (async () => {
     // Create a client
     const client = new Pulsar.Client({
       serviceUrl: 'pulsar://localhost:6650'
     });
   
     let count = 0;
   
     // Create a consumer
     const consumer = await client.subscribe({
       topic: 'persistent://public/default/my-topic',
       subscription: 'sub1',
       subscriptionType: 'Shared',
       ackTimeoutMs: 10000,
       listener: function(msg, consumerArg) {
         console.log(new Date().toLocaleString(), msg.getData().toString());
         delay(1000).then(() => {
           consumerArg.acknowledge(msg);
           consumerArg.close();
         })
       }
     });
   })();
   ```
   Crashes with the following output:
   ```
   FATAL ERROR: Error::New napi_get_last_error_info
    1: 0x555d20446711 node::Abort() [node]
   2020-04-13 13:04:10.834 INFO  ConsumerImpl:894 | 
[persistent://public/default/my-topic, sub1, 0] Closed consumer 0
    2: 0x555d20386273 node::FatalError(char const*, char const*) [node]
    3: 0x555d2038627c  [node]
    4: 0x555d20416d11 napi_fatal_error [node]
    5: 0x7f7ab97e6f1a  
[/home/guilherme/Projects/pulsar-client-node/build/Release/Pulsar.node]
    6: 0x7f7ab982af2a Consumer::Close(Napi::CallbackInfo const&) 
[/home/guilherme/Projects/pulsar-client-node/build/Release/Pulsar.node]
    7: 0x7f7ab98313c6 
Napi::ObjectWrap<Consumer>::InstanceMethodCallbackWrapper(napi_env__*, 
napi_callback_info__*) 
[/home/guilherme/Projects/pulsar-client-node/build/Release/Pulsar.node]
    8: 0x555d203fbf05  [node]
    9: 0x555d2062b657 
v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) 
[node]
   10: 0x555d2062ba21  [node]
   11: 0x555d2062c2da  [node]
   12: 0x555d2062cbf6 v8::internal::Builtin_HandleApiCall(int, unsigned long*, 
v8::internal::Isolate*) [node]
   13: 0x555d20db6e99  [node]
   Aborted (core dumped)
   ```
   Before the PR, the second call to Close would fail with an Already Closed 
error, but without crashing Node.
   
   I wrote the original listener implementation, thanks for cleaning it up! 
Most of the reason it was messy was that I couldn't find a better way to not 
crash and not leak any memory. It's really annoying due to how the pulsar C 
interface was made.
   
   The problem is that the C interface creates a `pulsar_consumer_t` on the 
stack and passes it to the message listener 
([here](https://github.com/apache/pulsar/blob/master/pulsar-client-cpp/lib/c/c_ConsumerConfiguration.cc#L52)).
 The consumer it receives is a shared pointer, but the one that is passed to 
the message listener can't be used after the original message listener function 
has returned due to this. I think the golang client wrapper workaround for this 
leaks memory, but I'm not sure. It saves a pointer to the consumer and channel 
to be used by the listener but I can't find where it deletes the pointer.
   
   Maybe we could add a function to the C interface that clones a 
`pulsar_consumer_t`, creating a new shared pointer to the same C++ consumer, 
and that has to be freed manually? This would allow libraries like this to 
clone the consumer received by the message listener callback to use it later to 
ack the message. That would simplify wrapper libraries a lot.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to