Thursday, November 09, 2006

Streamlining remote notifications

Mridul recent post highlights a point where XMPP could improve its presence notification model when presence subscribers are distributed amongst many servers. That said, the described behavior is by no mean specific to XMPP and is also found in SIP/SIMPLE early specification. As the issue exhibit some commonalities in both protocols, it is not extraordinary that the proposed solutions to decrease the network traffic generated by notifications revolve around notifying lists of subscribers instead of notifying each subscriber in turn. This is a rather common design in many publish/subscribe, where subscriptions' lists are advertised to the brokers nearest to the subscribers, with a task for them to perform the final notification. When applied in the context of XMPP, the driving idea is to delegate the atomic notification to the home presence server for the concerned domain.

Obviously the expected gain only results from a steamlined traffic between servers. The most noticeable gains would only be achieved when a particular user has more than one contact located on a remote server. In an adverse case presenting a widely spread distribution of remote subscribers (i.e. many remote subscribers each on different home servers), the gain would certainly be lower than expected.

The very nature of XMPP, with its persistent presence subscriptions, implies that the two cases in which a large number of presence packets will be exchanged are at the begining and end of a user’s session:

  • When the initial presence is published after a user login,
  • When the final presence is published at log out.

At a user login, an XMPP client delegates the appropriate presence notifications to the user’s home server; an initial presence will combine two separate processes:

  • A notification of the user's presence to all the watchers of its presence state,
  • A probe of each user's subscriptions to receive the contacts' presence states.

At logout time, only the notification of the final “unavailable” presence to all watchers is taking place.

I disagree with the way the problem is presented in the post, as the described use case assumes that the presence subscriptions between users on each server are symmetrical. Although that may account for a majority of cases, this cannot be extended as a generic case.

I also disagree with the underlying assumption that the two processes of notifying all watchers and probing to receive contacts' presence states are symmetrical. XMPP specifically differentiate between "presence-out" (outgoing notifications) and presence-in (incoming notifications). In effect, probes only occur once at the beginning of a user's session, whereas notifications will happen for every user's presence state change. As a result, I think these two processes have to be handled differently. I also believe support for these two processes would be best discovered and implememented independently by servers. Consequently:

  • Probing multiple contacts' presence states is a one time operation and can leverage XEP-0033 Extended Stanza Addressing to group all target JIDs in a single stanza. The probe result can be returned by the contacts home server using the same mechanism.
  • Notifying watchers requires establishing a transient dynamic watchers list on the contacts' home server. This list's address would then be used when sending notifications in order to minimize the inter-server traffic. The contacts' home sever will then be responsible for the local notification of every contact's resouces.

In this later process, I believe that XEP-0144: Roster Item Exchange would be more appropriate that XEP-0033 for the watcher list management. After all, the watcher list we are trying to build is nothing but a roster extract for the subscribers of a particular domain. The XEP-0144 extension provides all necessary management features to add/delete entries in the list. In our particular use case, I think the proper container is best provided by an InfoQuery stanza. An illustration of this approach is given bellow, which assumes the multi-notification service has previously been discovered through XEP-0030:

<iq to="notifier.denmark.lit"  from="" 
       type="set" id="1234">
  <x xmlns=''>
    <item action="add" jid="rosencrantz@denmark.lit"/>  
    <item action="add" jid="guildenstern@denmark.lit"/>         
<iq to="" from="notifier.denmark.lit/a341ff7cd2"
       type= "result" id="1234"/>

<presence to="notifier.denmark.lit/a341ff7cd2" from=""/>

You will note how the notification service returns the list address in the InfoQuery result, and how this qualified address is used for sending the presence stanza. If the list needs to be later updated during the user's session, it can be achieved incrementally:

<iq to="notifier.denmark.lit/a341ff7cd2"  from="" 
       type="set" id="3456">
  <x xmlns=''>
    <item action="add" jid="hamlet@denmark.lit"/>  
<iq to="" from="notifier.denmark.lit/a341ff7cd2"
       type= "result" id="3456"/>

In order to keep the management of the list simple, I would make the list transient for the duration of a user's session only. The overhead of re-creating it for every user's login is largely offset by a management that do not have to deal with permanent remote lists. The watcher list can be removed either when the final presence "unavailable" is sent to the multi-notification service, or by using a specific InfoQuery request extended with XEP-0144.

The possible side effects related to glitches in communication between the servers will have to be addressed separately using the mechanisms that are currently under discussion at the JSF.

Technorati Tags: , , ,