strongloop / strong-mq

MQ API with cluster integration, implemented over various message queues.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Subscribe to multiple topics not supported by native adapter

bajtos opened this issue · comments

As a sl-mq user, I want to use a single sub-queue to receive updates on multiple topics.

sub.subscribe('connect', onConnectFn);
sub.subscribe('close', onCloseFn);
// etc.

The current API gives an impression that it should be possible. The implementation in the native adapter does not seem to support this use-case.

I also want to selectively unsubscribe from some topics, e.g.

sub.unsubscribe('connect');
// still subscribed to 'close' topic

Is this a missing feature, or am I trying to use the API incorrectly (given it's not possible to subscribe to multiple topics in the first place)?

Multiple subscriptions are allowed ("Add your listener to the 'message' event directly when subscribing multiple times, "), so yes, its a bug in the native adapter (and a bug in my tests that I don't check for this).

Unsubscribe is supported by some brokers, I could implement, I didn't think it really useful, but now I guess I'm wrong. If socket.io needs that we can add to the native adapter, adding it to the others will take more time than we have now.

From the documentation for sub.subscribe():

`listener` is optional, it will be added as a listener for the `'message'` event if
provided. Add your listener to the `'message'` event directly when subscribing multiple
times, or all your listeners will be called for all messages.

In your example, all messages matching 'connect' or matching 'close' would get directed to the queue, and emitted as 'message' events... and both Fn would be called with both messages.

Is this what you saw? There is also an event listener leak when a queue is closed, which you might have seen.

I think it was me misunderstanding the API and not reading the documentation. Which probably means that other users are likely to run into the same problem.

Thinking about it again, having subscribe to accept a message listener is a nice shortcut if you subscribe to a single topic, but yields a code that does not what you would expect when used with multiple topics.

sub.subscribe('connect', onConnectFn);
sub.subscribe('close', onCloseFn);
// etc.

In the code above, it's confusing that both callback will be called for every message received.

I strongly suggest to modify the API in such way that it's more difficult to unintentionally do a wrong thing. (Allow our users to fall into the pit of success).

commented

I ran into the same problem.
Can you provide an example on how to subscribe to different topics on the same queue?

I would expect that the callback is only called for the appropriated topic.

Here is my code and cache.set gets called but I published a cache.get message.

var subQueue = connection.createSubQueue('mq-cache');
  var pubQueue = connection.createPubQueue('mq-cache');

  subQueue
  .subscribe('cache.get', (msg) => {
    Cacheitem.readCacheitem(msg.type, msg.key, (err, data) => {
      if (err) return;

      pubQueue.publish(data, 'cache.get.result.' + msg.key);
    });
  })
  .subscribe('cache.set', (msg) => {
    Cacheitem.writeCacheitem(msg.type, msg.key, msg.data, (err, data) => {

    });
  });

@gkTim Why are you using strong-mq? It does what it does... but we never found it useful and are no longer developing it.

Every person who I've heard from who is trying to use it misunderstands what its for, and would be better off using something else, which is why I ask what your purpose is.

commented

@sam-github Thanks for your answer.

In my case I would like to use it to create rabbit-mq message queues so my different microservices can communicate without knowing each other directly. Also I want to use work queues to load balancing the work between multiple instance of a service.

Am I getting the wrong idea of strong-mq and there is a better way to do this with strongloop and rabittMQ?
At the moment It does what I expected expect the above mentioned.

It would be better to directly use the underlying module, I added a note to this effect:

https://github.com/strongloop/strong-mq#strong-mq-clustering-of-applications-on-top-of-message-queues