Hi,
When running a soak on presence with RLS NOTIFY requests are by far the
most common. Further, especially with RLS in place, performance of
Kamailio presence can be quite limited. The writers of the presence
RFCs do seem to acknowledge that this is indeed an issue - hence the
restrictions on the rate at which NOTIFY requests can be sent.
I am looking for ways to sensibly reduce the number of NOTIFYs
generated, and in this case, it seems that the presence module is
actually sending them more frequently than the specification says it
should anyway.
Reducing the number of NOTIFYs sent doesn't just help with presence, but
it should also reduce the amount of work that the RLS module has to do
too - as it will receive (and have to process) less NOTIFYs as well.
Of course I am open to other ways to approach this problem. Another
thing I have been considering is setting the flags and fields I have
discussed below but not sending NOTIFYs right away at all. I would then
have a timer task (perhaps at the 100ms you suggest below) that
generates outstanding NOTIFYs - but not at a rate of more than once per
five seconds for each presentity. Effectively, this timer task would be
a notifier, which I think is one of the things suggested recently on the
list.
Regards,
Peter
On Fri, 2012-03-30 at 10:01 +0200, Klaus Darilion wrote:
On 29.03.2012 23:19, Peter Dunkley wrote:
Hi,
RFC 3856 section 6.10 states: "A PA SHOULD NOT generate notifications for
a single presentity at a rate of more than once every five seconds."
I wonder if this is useful. E.g. a user tries to call somebody, but the
target is busy. Thus, the call will last maybe 3 seconds having the
dialog states: trying, proceeding, early, terminated.
How is it supposed to work? It just sends trying, but no the others? Or
will they be queued, so only trying, and 5 seconds later, terminated is
sent?
I don't understand what this has to do with calls. I am just talking
about NOTIFY requests from presence after a change in presentity or a
SUBSCRIBE.
I would like to add this to the presence module (making the rate
configurable).
I have an idea as to how I would like to do it:
- Add a last notified time-stamp field to each presentity
- Add a updated since last notified flag field to each presentity
- Add a notify required flag field to each active_watcher
- When a presentity is updated the last notified time-stamp is checked.
If the time is far enough in the past the notifies are sent and the
time-stamp is updated. If enough time has not passed the updated since
flag is set for the presentity and the notify required flag is set for all
active_watchers of that presentity.
- When a presentity is subscribed to (this includes re-subscribes) the
last notified time-stamp is checked. If the time is far enough in the
past the (single) notify is sent and the time-stamp is updated. If enough
time has not passed the updated since flag is set for the presentity and
the notify required flag is set for this active_watcher record.
RFC3265 states that a NOTIFY MUST sent immediately after every SUBSCRIBE.
Ah... But define immediately. A 2XX response should also be sent
immediately after every SUBSCRIBE, but the timeout is 64*T1 (32
seconds). So a NOTIFY that, in many cases, comes out right away, or in
the worst case within 5 to 10 seconds, should count as immediate.
- A timer (the
minimum time between subscribes - default 5 seconds) is
run. On expiry a query is done on the presentity table for presentities
that have been updated _AND_ the last notified time is more than the
minimum time ago. For each of these presentities, a query is done on the
active_watchers for watchers of that presentity that have the notify
required flag set. Notifies containing the presentities are then sent to
the watchers waiting on them.
This should ensure that no presentity notifies more than it should, while
ensuring that all changes are (eventually) sent out, and all subscribes
result in a notify (eventually) being sent. Eventually being typically
within 5 seconds and in under 10 seconds in the worst case (assuming the
default setting of 5 seconds).
Can anyone see any problems with this?
I wonder why you delay NOTIFYs for (re)SUBSCRIBEs? On (re)SUBSCRIBEs
just NOTIFY with last published state and do not set the "notify
required" flag. Then it may happen that the minimum NOTIFY interval is
not maintained the first few seconds after a (re)SUBSCRIBE but IMO this
is not that bad and enables immediate notification after every
(re)SUBSCRIBE.
As you say, if I receive a PUBLISH and then a re-SUBSCRIBE to a
presentity then I will send out NOTIFYs too often. I have seen (bad)
clients that re-PUBLISH immediately before re-SUBSCRIBE and un-PUBLISH
immediately before un-SUBSCRIBE. If a lot of people use these bad
clients then you have a problem.
Are there any
objections to me implementing this?
Make it configurable :-) E.g. setting "minimum_notification_delay" to 0
disables the feature.
Of course :-)
It may also increase DB load and cause more
race-conditions (to be
resolved with DB-transactions) due to more DB lookups.
It also helps with a race condition I think I am seeing (and similar to
that recently discussed on this list) where you can have more than one
NOTIFY outstanding on a dialog at a time, and if these get out of
sequence then you do definitely get problems.
While there may be more DB load overall, I suspect that because this
helps spread it out somewhat it should make the performance more even.
Also many of these queries will be much simpler and lighter as I do not
need to always retrieve the presentity field, which is particularly
large.
E.g. what if the timer finds a presentity for which
NOTIFYs needs to be
sent and - while iterating over all the presentities - a new PUBLISH is
received which triggers immediate NOTIFY. It may happen that both
processes manipulate the active watchers table at the same time (notify
required flag).
Is this not also a problem with rls_presentity which uses a very similar
mechanism already?
In theory running a (5 second) timer could make
presence "lumpy" in the
same way RLS is (see my previous email). However, if this proves to be
the case I believe the same mechanism I have proposed for RLS can be used
here.
Why run the timer only every 5 seconds? Run it every second (or 100ms)
then it should not be lumpy anymore.
regards
Klaus
--
Peter Dunkley
Technical Director
Crocodile RCS Ltd