1
votes

Smack version: 4.2.4

When a large number of messages (normal messages and delay-resent messages) comes enters the android client, smack creates 100~200 sleeping Smack Cache Executor threads. This sudden influx of threads causes the android client to become unresponsive (ANR error).

Under normal operations, there would be at least 2 Smack Cache Executor threads and the application would be operating with a total of 50-60 threads.

Messages of type delay offline storage is handled 'Flexible Offline Message Retrieval' protocol. However, those of normal and delay-resent messages don't seem to have any special protocol and there are no clear solutions for the thread count influx.

A large number of messages here refer to 600+ resent messages and normal messages incoming within seconds.

Any help or advice on this matter is much appreciated. Many thanks in advance!

Edit 1:

3 Stanza Listeners are setup when connection to XMPP is authenticated. One for Presence, one for Message and one for IQ. They are as follows:

public void addPresenceStanzaListener(){
    if (presenceStanzaListener != null) {
        connection.removeSyncStanzaListener(presenceStanzaListener);
    }

    StanzaFilter presenceStanzaFilter = new StanzaTypeFilter(Presence.class);

    presenceStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process presence stanza
        }
    };
    connection.addSyncStanzaListener(presenceStanzaListener, presenceStanzaFilter);
}

public void addMessageStanzaListener(){
    if (messageStanzaListener != null) {
        connection.removeSyncStanzaListener(messageStanzaListener);
    }

    StanzaFilter messageStanzaFilter = new StanzaTypeFilter(Message.class);
    messageStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process message stanza
        }
    };

    connection.addSyncStanzaListener(messageStanzaListener, messageStanzaFilter);
}

public void addIQStanzaListener(){
    if (iqStanzaListener != null) {
        connection.removeSyncStanzaListener(iqStanzaListener);
    }

    StanzaFilter iqStanzaFilter = new StanzaTypeFilter(IQ.class);
    iqStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process IQ stanza
        }  
    };

    connection.addSyncStanzaListener(iqStanzaListener, iqStanzaFilter);
}

How Smack Cache Ex thread count increase is triggered:

  1. Turn off Internet connection
  2. Spam 600+ messages
  3. Turn Internet connection back on (at this point, in ejabberd point of view, android client was never disconnected from it)
  4. The moment client is connected to XMPP, Smack Cache Ex thread count increases by at least 100.
1

1 Answers

0
votes

You probably use asynchronous stanza listener when you should use synchronous ones.

Ultimately you should be able to track down the exact listener (assuming it is in fact caused by a StanzaListener, but even that is not verified right now) which is creating all those threads. If you identified and it is a listener setup by Smack, then you should probably report that as issue in the Smack community forums. If it is a listener setup by you, then you possibly want to use synchronous listener or Smack's AsyncButOrdered utility to reduce the number of threads.