Default behavior for multiple clients with same bare JID and priority

I’m doing some simple testing to understand the (default) behavior of Openfire when multiple clients are connected (and disconnected/reconnected) that have the same bare JID and priority. To test this I wrote a pretty trivial client program in Java, using the Smack library:

package com.test.testxmppclient;

import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.jid.EntityBareJid;

import java.io.IOException;

public class FakeAnyClient {
	public static void main(String[] args) throws SmackException, IOException, XMPPException, InterruptedException {
		XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
				.setUsernameAndPassword("client-a", "client-a")
				.setXmppDomain("test.com")
				.setHost("localhost")
				.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled)
				.build();
		AbstractXMPPConnection connection = new XMPPTCPConnection(config);
		connection.connect();
		connection.login();
		System.out.println("Logged in as " + connection.getUser());
		Presence presence = new Presence(Presence.Type.available);
		presence.setPriority(0);
		connection.sendStanza(presence);
		
		ChatManager chatManager = ChatManager.getInstanceFor(connection);
		chatManager.addIncomingListener(new IncomingChatMessageListener() {
			@Override
			public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
				System.out.println("New message from " + from + ": " + message.getBody());
			}
		});
		
		System.in.read();
		connection.disconnect();
	}
}

I’d start 2 instances like this, and I run a third client, connecting with different credentials (“client-b”) using an off-the-shelf XMPP chat program (gajim in my case).
Now when I send some chat messages from client-b (gajim) to client-a (2 instances my program), each of those messages gets delivered to one of the two instances, but in a somewhat piculiar pattern: sometimes all the messages get delivered to the same instance while other times the first message gets delivered to one instance while the remaining messages get delivered to the other instance. This behavior already seems very interesting and I would like to understand it better, but what is even more interesting and the main point of what I would like to understand is what happens when one of my “client-a” programs, which received some (or all) of the messages, terminates.
When I gracefully shut it down (by pressing any key in this case) and the connection.disconnect(); is called nothing surprising happens; thats just it, and any next mesasges will be delivered to the remaining instance. However when I kill it (or just exit it without calling connection.disconnect();) I see different things happening each time:

  • Sometimes all of the messages that instance received get redelivered to the other instance
  • Sometimes some of the messages that instance received get redelivered to the other instance
  • Sometimes nothing happens ; none of the messages that instance received get redelivered to the other instance
    When there is no other client and the ‘killed’ client just reconnects shortly after, I havent seen any messages been redilvered to the “new” instance.

The best I can make of this that when a client “disappears” (without calling disconnect) and there are other clients (with the same priority?) there is some mechanism that redelivers messages which have been delivered less than X time ago. However I could not find any documentation about this while I imagine behavior like that would have to have been thoughtfully designed.
So finally my questions:

  • Is this behavior as expected?
  • Is there any documentation about it?
  • Can it be adjusted? (ie, can such redelivery be disabled, can the timeout for it be changed)?
  • Can a client somehow indicate that a message is handled and therefore should not be redelived in case the connection is lost (ie, an ACK)?
  • This behavior also implies that messages which have been delivered will still be kept by the server for some time (at least until this supposed redelivery timeout expired). I did not find any place in the database where they seem to be kept. Where are they kept?

I hope someone can help me out here, as using xmpp/Openfire in my application requires thourough understanding of what happens in these cases.