nats-io / nats.ts

TypeScript Node.js client for NATS, the cloud native messaging system
https://www.nats.io
Apache License 2.0
178 stars 13 forks source link

"Max" option may leaks into other subscriptions #91

Closed trading-peter closed 4 years ago

trading-peter commented 4 years ago

If you run the following code the following is expected:

  1. A one time message is send and received using a inbox. max is set to 1.
  2. The inbox is unsubscribed as expected
  3. Two messages (with a 1 second delay in between) "hello world 1" and "hello world 2" are send and received.

What actually happens is:

  1. One time message is via inbox is send and received. Then unsubscribed as expected.
  2. The first "hello world 1" message is send and received
  3. Unexpectedly the "hello.*" subscription is canceled (if you debug the code you can see that "max" is set to 1 all the sudden.
  4. The second message "hello world 2" is not received but should have been.
const NATS = require('ts-nats');

async function run() {
  const client = await NATS.connect({
    url: 'nats://127.0.0.1:4222',
    payload: 'json',
    maxReconnectAttempts: -1,
    reconnectTimeWait: 2000
  });

  client.on('unsubscribe', sub => {
    console.log('unsubscribed', sub.subject);
  })

  await client.subscribe('hello.*', processMsg);

  // If you comment the next three lines out, "hello world 2" will be received.
  const pubSubInbox = client.createInbox();
  await client.subscribe(pubSubInbox + '.*', processMsg, { max: 1 });
  client.publish(`${pubSubInbox}.onetime`, { onetime: true });

  setTimeout(() => {
    console.log('Send hello world once');
    client.publish('hello.world', { hello: 'world 1' });

    setTimeout(() => {
      console.log('Should send hello world a second time, but doesn\'t arrive');
      client.publish('hello.world', { hello: 'world 2' });
    }, 1000);
  }, 1000);
}

function processMsg(err, msg) {
  console.log('received', msg);
}

run();

If you comment the inbox code out, everything is working fine.

aricart commented 4 years ago

@pkaske - found it - the issue is if max is set when the subscription is called a bogus subscription id is sent for the unsubscribe. As a workaround until I push a release in the next couple of days, you can do an sub.unsubscribe(n).

aricart commented 4 years ago

Thank you very much for pointing this issue.

aricart commented 4 years ago

I have released v1.2.15. npm install ts-nats@latest

trading-peter commented 4 years ago

Oh wow that was fast! Awesome 🙂 Thank you