ralphm's blog

Thursday, 21 April 2005

Pubsub subscription tracking

Where do I get stuff from?

Recently, there has been more and more discussion on the standards-jig and jdev mailing lists about Publish-Subscribe, in part because of updates to the User Avatar JEP. One discussion is about keeping track of your pubsub subscriptions. For clarity, the context is the use of pubsub in regular Jabber IM deployments. Pubsub is also useful in other contexts, but the IM context carries some inherent assumptions. I make three observations here, and expand on this further below.

No central pubsub service

What we will most probably see, is that entities will have subscriptions on a multitude of pubsub services, scattered troughout the Jabber universe.

No subscription notification

When send an initial subscription request to a pubsub node, you get a reply stating if you were indeed subscribed, or that the subscription is pending and waiting for approval of the node owner. Also, when your subscription is cancelled, you have no way of knowing what happened.

Subscriptions are bound to a JID.

This seems obvious, but what I want to point out here is that if you use a bare JID (without a resource part) to subscribe, notifications will go to the resource (client) with the highest priority. If you subscribe using a full JID (with a resource part), notifications will only go to the specified resource.

A pubsub service usually allows you to query your existing subscriptions, using the affiliations element. This is similar to fetching your roster using jabber:iq:roster. However, my first observation above causes this to be troublesome. Since my subscriptions can be on any pubsub service, I'd have to know which services I have subscriptions at.

Unlike the normal roster, pubsub does not have a way to relay changes in your subscriptions, as explained above. This means that if my subscription changed since I last queried for my subscriptions, I have no way of knowing. Sure, if I suddenly get notifications from a node to which my subscription was previously pending, I could refetch the list of subscriptions. But that amounts to polling, which is cumbersome. It would be much nicer to be notified of such changes.

To counter these two problems, one could register with the pubsub services, like with transports, and have the services in your roster. The client could then simply look in the roster for the services to query using the affiliations element. Like with rosters, as soon as the affiliations were first fetched after getting presence from the entity, the service could send out notifications to the entity that represent changes in affiliations (not only subscriptions) with that service. This could be done by sending notifications from the root node, having an affiliations element in the item body, or by allowing such an element to be sent as a direct child of the event element, similar to the notification of deleted nodes. After sending unavailable presence, the notifications would stop.

My third observation above says that it makes no sense to subscribe using your bare JID when running concurrent clients, because notifications will only go to one of the connected resources. For things like avatars, that is most likely not desirable. Adding subscriptions for each resource (depending on what the client supports) is one alternative. One other solution is to invent a new (boolean) node configuration option, that states that, if set, the pubsub service needs to check which of the resources support the namespace of the payload of the node's items, and send out notifications to all of those. This requires the service to subscribe to the presence of the resources in question. Registering with the pubsub service, again, solves this. The service could then use Entity capabilities and Service Discovery for checking the namespace support.