mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-22 20:47:57 +01:00
Add StreamManagemtCounterError
to allow graceful connectionClosedOnError() disconnects, since we received a bunch of reports where the counter seems wrong, which is causing a NPE in a thread pool executor, causing the VM or Android App to terminate. Now we throw the StreamManagementCounterError instead.
This commit is contained in:
parent
7897fca876
commit
aa8daba1cf
2 changed files with 64 additions and 2 deletions
|
@ -16,7 +16,11 @@
|
|||
*/
|
||||
package org.jivesoftware.smack.sm;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
public abstract class StreamManagementException extends SmackException {
|
||||
|
||||
|
@ -52,5 +56,59 @@ public abstract class StreamManagementException extends SmackException {
|
|||
super("Stream IDs do not match. Expected '" + expected + "', but got '" + got + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public static class StreamManagementCounterError extends StreamManagementException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final long handledCount;
|
||||
private final long previousServerHandledCount;
|
||||
private final long ackedStanzaCount;
|
||||
private final int outstandingStanzasCount;
|
||||
private final List<Stanza> ackedStanzas;
|
||||
|
||||
public StreamManagementCounterError(long handledCount, long previousServerHandlerCount,
|
||||
long ackedStanzaCount,
|
||||
List<Stanza> ackedStanzas) {
|
||||
super(
|
||||
"There was an error regarding the Stream Mangement counters. Server reported "
|
||||
+ handledCount
|
||||
+ " handled stanzas, which means that the "
|
||||
+ ackedStanzaCount
|
||||
+ " recently send stanzas by client are now acked by the server. But Smack had only "
|
||||
+ ackedStanzas.size()
|
||||
+ " to acknowledge. The stanza id of the last acked outstanding stanza is "
|
||||
+ (ackedStanzas.isEmpty() ? "<no acked stanzas>"
|
||||
: ackedStanzas.get(ackedStanzas.size() - 1).getStanzaId()));
|
||||
this.handledCount = handledCount;
|
||||
this.previousServerHandledCount = previousServerHandlerCount;
|
||||
this.ackedStanzaCount = ackedStanzaCount;
|
||||
this.outstandingStanzasCount = ackedStanzas.size();
|
||||
this.ackedStanzas = Collections.unmodifiableList(ackedStanzas);
|
||||
}
|
||||
|
||||
public long getHandledCount() {
|
||||
return handledCount;
|
||||
}
|
||||
|
||||
public long getPreviousServerHandledCount() {
|
||||
return previousServerHandledCount;
|
||||
}
|
||||
|
||||
public long getAckedStanzaCount() {
|
||||
return ackedStanzaCount;
|
||||
}
|
||||
|
||||
public int getOutstandingStanzasCount() {
|
||||
return outstandingStanzasCount;
|
||||
}
|
||||
|
||||
public List<Stanza> getAckedStanzas() {
|
||||
return ackedStanzas;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success;
|
|||
import org.jivesoftware.smack.sm.SMUtils;
|
||||
import org.jivesoftware.smack.sm.StreamManagementException;
|
||||
import org.jivesoftware.smack.sm.StreamManagementException.StreamIdDoesNotMatchException;
|
||||
import org.jivesoftware.smack.sm.StreamManagementException.StreamManagementCounterError;
|
||||
import org.jivesoftware.smack.sm.StreamManagementException.StreamManagementNotEnabledException;
|
||||
import org.jivesoftware.smack.sm.packet.StreamManagement;
|
||||
import org.jivesoftware.smack.sm.packet.StreamManagement.AckAnswer;
|
||||
|
@ -1642,7 +1643,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
return Math.min(clientResumptionTime, serverResumptionTime);
|
||||
}
|
||||
|
||||
private void processHandledCount(long handledCount) throws NotConnectedException {
|
||||
private void processHandledCount(long handledCount) throws NotConnectedException, StreamManagementCounterError {
|
||||
long ackedStanzasCount = SMUtils.calculateDelta(handledCount, serverHandledStanzasCount);
|
||||
final List<Stanza> ackedStanzas = new ArrayList<Stanza>(
|
||||
handledCount <= Integer.MAX_VALUE ? (int) handledCount
|
||||
|
@ -1651,7 +1652,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
Stanza ackedStanza = unacknowledgedStanzas.poll();
|
||||
// If the server ack'ed a stanza, then it must be in the
|
||||
// unacknowledged stanza queue. There can be no exception.
|
||||
assert(ackedStanza != null);
|
||||
if (ackedStanza == null) {
|
||||
throw new StreamManagementCounterError(handledCount, serverHandledStanzasCount,
|
||||
ackedStanzasCount, ackedStanzas);
|
||||
}
|
||||
ackedStanzas.add(ackedStanza);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue