> I have been struggling with an issue where more than occasionally the 
> delayedResponseQueue will be filled with empty responses until the server 
> eventually runs out of memory. The client is JSJac but I am not really 
> focused on that implementation, I just want to try and protect the server 
> from being over run by any client.

We're running into the same issue now using Strophe, so it probably isn't due 
to the client.

> So here is what is happening:
> 
> Here are the RIDs 
> 
> 318 never made it through.
> 
> Last sent response = 316
> Highest Read = 317
> Current = 319
> Window = 319
> 
> The coding of 
> 
> requestExpired {
>  ... ... 
> 
>  while(!requestsWindow.isEmpty() && requestsWindow.firstKey() <= 
> req.getRid()) {
>    write0(boshHandler.getEmptyResponse());
>   }
> 
> Coupled with 
> 
> write0 {
>  if (requestsWindow.isEmpty() || requestsWindow.firstKey() > highestReadRid) {
>     delayedResponseQueue.offer(response);

This if statement is the part I don't understand.  It makes sense that you 
would queue the stanza for delivery if the requestsWindow is empty, but why is 
it queued when the first request in the requestsWindow has a rid greater than 
the highestReadRid.  Going through the code, I can see how the firstKey could 
be higher than the highestReadRid, but I don't understand why it is allowed to 
be possible.

Specifically, looking at this for loop in 
BoshBackedSessionContext.insertRequest:

for (;;) {
        // update the highestReadRid to the latest value
        // it is possible to have higher RIDs than the highestReadRid with a 
gap between them (e.g. lost client request)
        if (requestsWindow.containsKey(highestReadRid + 1)) {
            highestReadRid++;
        } else {
            break;
        }
}

If an rid is skipped, as in the scenario you outlined, then the highestReadRid 
won't be incremented to 319 and will remain as 317 forever.  Which causes the 
firstKey to be greater than the highestReadRid.  That loop doesn't seem right 
to me.

Thoughts?  


> Can easily lead to an infinite loop writing empty responses to the 
> delayedResponseQueue.
> 
> So in trying to fix this I am having trouble understanding why this would be 
> done in a loop ? 
> 
> My first instinct is to change the while loop to an if statement but I assume 
> there is a good reason it was implemented this way, I just cannot see it.
> 
> Is is not sufficient to write a single empty response when the request 
> expires in the window? 

Good question.

> 
> The spec is of very little help here so any thoughts would be greatly 
> appreciated.

Reply via email to