Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple handlers for subscriptions #54

Closed
oberstet opened this issue Feb 26, 2014 · 5 comments
Closed

Multiple handlers for subscriptions #54

oberstet opened this issue Feb 26, 2014 · 5 comments

Comments

@oberstet
Copy link
Contributor

Attaching multiple client-side event handlers to one and the same subscription:

function handler1(args, kwargs, details) { ... }
function handler2(args, kwargs, details) { ... }

session.subscribe('com.myapp.topic1').then(
   function (subscription) {
      subscription.watch(handler1);
      subscription.watch(handler2);
   }
);

Essentially, the following 2 would be equivalent

session.subscribe('com.myapp.topic1', handler1);

and

session.subscribe('com.myapp.topic1').then(
   function (subscription) {
      subscription.watch(handler1);
   }
);

The difference is: the latter form allows to attach multiple event handlers to one and the same subscription.

@kousu
Copy link

kousu commented Feb 26, 2014

This is my python bias speaking, but There Should On Be One Way To Do It. The first form is more intuitive, and keeps the code shorter (I don't understand why I care about a subscription; that should be an internal object).

What I want is the behaviour of jQuery: .subscribe() should append handlers to a list, and you should have an .unsubscribe() which optionally takes the (previously subscribed) function to unsubscribe.

My use case is this: I have a stream of numbers coming from my server, and I want to feed them to d3 plots, to a simulated robot on a plot, and to the console for debugging. Maybe the debug prints can sit in one or the other handler, but it would be awkward (and cut across js files) to have both viewing features in one function. If Autobahn doesn't do multiplexing, I'll need the function I pass to .subscribe() be a multiplexer instead of directly being handlers I actually care about.

@oberstet
Copy link
Contributor Author

Subscriptions are objects since for unsubscribing at the WAMP message level, you need to know the subscription ID - which is stored inside the JS subscription object returned.

Not sure if I get you: do you want attaching multiple handlers like this?

session.subscribe('com.myapp.topic1', handler1);
session.subscribe('com.myapp.topic1', handler2);

If so: this was the API of WAMP v1. Internally, subscriptions would be a dictionary indexed by topic. With WAMP v2 and pattern based subscriptions, this naive view of "topic ~ subscription" no longer holds true. Now, the subscription ID is returned asynchronously from the broker upon subscribing.

@oberstet
Copy link
Contributor Author

Removing a handler from the list would work as "unwatching":

session.subscribe('com.myapp.topic1').then(
   function (subscription) {
      subscription.watch(handler1);

      // stuff

      subscription.unwatch(handler1);
   }
);

Calling session.subscribe multiple times returns the same subscription object.

For this we need to either use a broker to detect a duplicate subscription and return the existing subscription ID. Or, have a client-side map that uses key material from topic and Options.

@goeddea
Copy link
Contributor

goeddea commented Mar 8, 2014

Agree with kousu that I shouldn't have to care where in my code I subscribe to a topic, and how often this happens.

My suggestion:

  • Allow multiple, separate subscriptions using the simple syntax of
    session.subscribe('com.myapp.topic1', handler1);
  • These all return separate subscription objects / IDs, and can be unsubscribed individually.
  • The library creates these objects, but only uses a single subscription under the hood

@codegastudio
Copy link

codegastudio commented Apr 14, 2017

Hi,

I had many subscription done on same topic name in different angular 2 component.

// in component 1
session.subscribe('com.myapp.topic1', handlerComponent1)

// in component 2
session.subscribe('com.myapp.topic1', handlerComponent2)

I need to unsubscribe them.

var subscriptions = session.subscriptions;
for (var index in subscriptions) {
  let subs = subscriptions[index];
  for (let sub_index in subs) {
    let sub = subscriptions[index][sub_index];
    let topic = sub.topic;
    sub.unsubscribe().then(res => {
      console.log(topic, 'unsubscribe', res);
    });
  }
}

And this now than troubles come.
I had all the time one subscription witch is not unsubscribe.

Any idea ?

UPDATE
I found a way !
Subscriptions as grouped in different arrays.
So i concat all of them and loop on each subscription in this single new array and this work.
Some unsubscribe Subscription promise return false but they are not anymore activated so i don't catch anymore handler on unsubscribed topic.

var subscriptions = [];
for (let index in session.subscriptions)
  subscriptions = subscriptions.concat(session.subscriptions[index]);
  for (let index in subscriptions) {
    let subscription = subscriptions[index];
    let topic = subscription.topic;
    session.unsubscribe(subscription).then(res => {
       console.log("unsubscribe", topic, res);
    });
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants