In my last post, I discussed the Resource List Service optimization to the SIP Events mechanism. The reader will recall that I argued that, while that optimization had value in certain specific circumstances, it does not universally improve scalability. Today I will discuss the Conditional Event Notification extension defined in RFC 5839.
As defined in RFC 3265, a SIP event subscription is soft-state. Soft-state is an extremely important concept in SIP and other IP based protocols, in that it makes networks more resilient to errors. But soft-state requires maintenance. In the case of an event subscription, if it the client does not refresh the subscription in some negotiated period of time, it goes away.
The client refreshes a subscription by sending a new SUBSCRIBE request in the existing dialog, that is, the dialog created by the initial SUBSCRIBE request. Other than being mid-dialog, the resulting transaction is similar to the initial one. The server responds (in the same dialog) with both a SIP response to the SUBSCRIBE request, and a NOTIFY request back towards the client.
That NOTIFY request contains the current state of the event. For the presence event, that state could conceivably be quite large. And for a long lived subscription, you can get a lot of subscription refreshes. For example, if you refresh every 30 minutes, a 24-hour long subscription will get a NOTIFY request for the initial subscription, 47 subscription refreshes, and a termination, for a total of 49 “maintenance” SUBSCRIBE requests. This is in addition to any notifications generated due to bona-fide state changes.
The Conditional Event Notification extension offers a mechanism to suppress some or all of these maintenance NOTIFY transactions. The mechanism uses an entity-tag, or ETag for short. An ETag is a kind of magic cookie that identifies a particular version of the state of an event. When the notifier sends an update to the event state, it can include an ETag. Then when the client needs to refresh a subscription, it can include the ETag in the subscription. The notifier then compares that ETag against the one for the current even state. If they match, it knows that the client’s view of the event-state is still current. The notifier can then avoid sending the NOTIFY request. This is similar to the idea of entity-tags in HTTP. In fact, this usage of ETags, and a similar usage for SIP PUBLISH, were inspired by this idea.
This mechanism does not only work for subscription refreshes. The client can also use it to resume a previous subscription, and suppress the contents of the initial NOTIFY. (It can’t suppress the initial NOTIFY entirely, as that transaction is critical for properly establishing a new subscription dialog.)
Conditional notification can be helpful when network bandwidth is scarce or expensive, such as in mobile wireless networks. It’s less helpful when bandwidth is plentiful, such as in wired broadband networks. While conditional notification reduces the NOTIFY requests that a notifier must send, it also increases the computational complexity of handling SUBSCRIBE requests. So, the server-side value of this optimization depends quite a bit on the software implementation of the notifier.
Even in the case of scarce bandwidth, this optimization has an implied assumption that the number of refresh NOTIFY requests is significant compared to the number of NOTIFY requests sent due to actual event state changes. If the event state changes rapidly, as it might in a subscription to user presence state–or even more so if that state includes location data, then the returns of conditional notification begin to diminish.
Additionally, since conditional notification is attractive to mobile wireless providers, it’s likely to be combined with other wireless-oriented optimizations – such as the RLS optimization I discussed last time. If you recall, a resource list subscription receives notification for state changes of each resource on the list, as well as any changes to the list itself. This greatly amplifies the number of NOTIFY requests sent for real state changes. When you stack both of these optimizations, you get diminishing returns compared to using each separately.
The reader may notice a pattern here. SIP was designed to work well for the general case. Most optimizations to SIP are designed for very specific situations. They tend to be less helpful, and sometimes even harmful, in the general case. When looking for ways to optimize a particular SIP network, one must be careful to make sure the network in question actually fits the implicit assumptions of the optimizations.