Bosh: combining multiple response into one body, but out of order

Matthew M
Added over 5 years ago

I found sometime the response stanza from server to BOSH client are combined into on response , which I think it's fine for performance improvement. However, sometime I found the sequence of the stanza I put into response are out of order in the final single element.

For example, I customized the code to send a roster-push to add a new buddy to the user, then immediately send the presence stanza of the new buddy to the user to indicate it has an new buddy and is online now.

Over TCP connection, it works perfectly, two stanzas were sent, roster-push first, followed by the presence-stanza.

But for the same Tigase code, when the end user is over BOSH, most of the time the order of the two stanza are flipped. The two stanzas are combined into one by Tigase, and the presence-stanza is ahead of the roster-push inside bosh .

I am trying to look for the code where Tigase combines multiple stanzas before sending to client, but could not find any. Could you point out where it is? I am trying to see what's the algorithm of this combining process, so maybe I could tune the interval between two stanzas.

Or, is there any way to force the flush of Bosh response from server to client to ensure the sequence?


Replies (3)

Added by Andrzej Wójcik IoT 1 CloudTigaseTeam over 5 years ago

I checked algorihm responsible for combining stanzas in one but it is very simple algorithm which append received stanzas to a queue and polls stanzas from a queue when response is generated. As I checked it, it looks like it is working fine.

Did you checked ordering of stanzas in body in HTTP response for your request or you checked it after preprocessing by a library? I'm asking this only to ensure as ordering could be changed after receiving data from server.

Now, answering your questions:

Stanzas are combined into one element by Tigase in BoshSession class - look for waiting_packets field.

Also there are additional properties which can be set for BOSH component to change it's behavior:

batch-queue-timeout - allows to set maximal timeout allowed for batching stanzas - by default 100ms

max-batch-size - allows to limit how many stanzas can be combined into one body - by default up to 15

Added by Matthew M over 5 years ago

Thanks for the information! Yes I browse the code you mention, seems that nothing should go wrong with the order....

However, I am examine the outgoing packets via the server side logs, before it even reaches the client, and the order is switched, sometime.

Here is what I've done in process an IQ request. Basically it updates the roster and do a roster-push to the client, then send the presence of the new roster items to the client. I am not sure if I did it in the right way or not:

  1. I send the roster-push packet via SessionManager.addOutPacket()

  2. I send the presence packet via results.offer()

Very likely, the presence stanza were packaged ahead of roster-push in the final packet sending to the client. Currently, I am adding a sleep(1000) between the two, then everything looks fine and in order.

So I wonder if I am missing some understanding in the basic structure or flow of Tigase outgoing packet queue management. Are SessionManager.addOutPacket() and results.offer() going through different queues, thus eventually they are packaged out of the order randomly?

    protected void processSetRequest(Packet packet,
            XMPPResourceConnection session, Queue<Packet> results,
            Map<String, Object> settings) throws XMPPException,
            NotAuthorizedException, TigaseDBException {

           //..... prepare some roster updates, create roster-push-packet

          roster-push-to-user: via SessionManager.addOutPacket( roster-push-packet )

          // send presence stanza




Added by Artur Hefczyc TigaseTeam over 5 years ago

I am very curious why are you sending roster push in a different way than the presence stanza? Sending a packet from plugin via SM oddOutPacket is not a part of plugin's API. All packets which are a result of the plugins processing should be submitted for further processing and delivery via results queue.

Have you based your code on the existing roster or presence plugin by any chance? Is there a construction like this in the Tigase's code?

A more proper way to make sure one packet is delivered before another packet, like in your code is to set a different priority for the packet. This should solve the problem. Using a sleep(1000) delay is not a good solution because if you have a high traffic installation all those sleep delays will kill your performance.