Hello,

The processing for presence.winfo and other events do require separate calls. This is because the processing of the dialogs in the first call can affect the processing of the dialogs in the second.

If all event types were handled in one call some processing would not occur until the next handling of the round - five seconds later.

It may well be the case that there is a bug in the loop as you described, but my statement from before still holds that the notifier stuff will never work properly in 3.3 due to DB limitations - even if you fix the bug you've found you will need to use the version in bit master to cope with any real load.

I suppose the DB limitations may not be an issue on a single server (non-resilient) presence configuration, but in that case you should use the default (non-notifier) setup for presence anyway.

Regards,

Peter

Shane Harrison <shane.harrison@paragon.co.nz> wrote:

Hi all,
I have a situation where subscriptions do not get notified and have tracked it down to a problem with the polled notify processing. Can you advise if this is a bug or correct my understanding of the code.

I am using kamailio 3.3.3 and have 1 notify process. I have enhanced the support for the ua-profile event (rfc 6080) , although I don't believe I have made any changes that directly impact the problem I am seeing.
 
When a new subscription arrives it is added to the active_watchers table, the 'updated' column is assigned a number in the range 0 - N-1, where N is effectively the total number of polled update tasks that are called in a round-robin fashion, distributed across the notify processes. In this case updated = 7.

In subscribe.c:
int update_subscription_notifier(struct sip_msg* msg, subs_t* subs, int to_tag_gen, int* sent_reply)
{
...
/* Set the notifier/update fields for the subscription */
subs->updated = core_hash(&subs->callid, &subs->from_tag, 0) %
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes);

The notify process periodically calls pres_timer_send_notify(), which calculates the round (the update task number) and does the notify update by checking the active_watchers table for entries with updated = round. The update is done twice, first for the event then for event.winfo.

In notify.c:
void pres_timer_send_notify(unsigned int ticks, void *param)
{
int process_num = *((int *) param);
int round = subset + (pres_waitn_time * pres_notifier_poll_rate
* process_num);
if (process_dialogs(round, 0) < 0)
{
LM_ERR("Handling non presence.winfo dialogs\n");
return;
}
if (process_dialogs(round, 1) < 0)
{
LM_ERR("Handling presence.winfo dialogs\n");
return;
}
}

In this instance process_num = 0, so round = subset. However subset is incremented in process_dialogs() in notify.c:

if (++subset > (pres_waitn_time * pres_notifier_poll_rate) -1)
subset = 0;

This means that round is incremented twice between calls to process_dialogs(round, 0), in my case round is always even, hence not detecting the subscription with updated = 7.

It seems that the subset increment should be done in pres_timer_send_notify() rather than in process_dialogs(). Is this correct?

Additionally, is there a need for the second call that only handles presence.winfo subscriptions? The code could be simplified by only making one call and processing all subscriptions for the round.
 
Kind regards
Shane Harrison


--
Imagination NZ Ltd
Level 6
92 Queens Drive
P0 Box 30449
Lower Hutt 5040

+64 4 5703870 Extn 875
+64 21 608919  (mobile)