mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-24 21:12:05 +01:00
Check if unacknowledged stanzas queue is full before adding to it
to avoid an IllegalStateException. Fixes SMACK-844.
This commit is contained in:
parent
0c134db072
commit
5ddaa623da
2 changed files with 64 additions and 1 deletions
|
@ -16,10 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack.sm;
|
package org.jivesoftware.smack.sm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.packet.Element;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
|
||||||
public abstract class StreamManagementException extends SmackException {
|
public abstract class StreamManagementException extends SmackException {
|
||||||
|
@ -110,5 +113,56 @@ public abstract class StreamManagementException extends SmackException {
|
||||||
return ackedStanzas;
|
return ackedStanzas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class UnacknowledgedQueueFullException extends StreamManagementException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final int overflowElementNum;
|
||||||
|
private final int droppedElements;
|
||||||
|
private final List<Element> elements;
|
||||||
|
private final List<Stanza> unacknowledgesStanzas;
|
||||||
|
|
||||||
|
private UnacknowledgedQueueFullException(String message, int overflowElementNum, int droppedElements, List<Element> elements,
|
||||||
|
List<Stanza> unacknowledgesStanzas) {
|
||||||
|
super(message);
|
||||||
|
this.overflowElementNum = overflowElementNum;
|
||||||
|
this.droppedElements = droppedElements;
|
||||||
|
this.elements = elements;
|
||||||
|
this.unacknowledgesStanzas = unacknowledgesStanzas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOverflowElementNum() {
|
||||||
|
return overflowElementNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDroppedElements() {
|
||||||
|
return droppedElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Element> getElements() {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Stanza> getUnacknowledgesStanzas() {
|
||||||
|
return unacknowledgesStanzas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnacknowledgedQueueFullException newWith(int overflowElementNum, List<Element> elements,
|
||||||
|
BlockingQueue<Stanza> unacknowledgedStanzas) {
|
||||||
|
final int unacknowledgesStanzasQueueSize = unacknowledgedStanzas.size();
|
||||||
|
List<Stanza> localUnacknowledgesStanzas = new ArrayList<>(unacknowledgesStanzasQueueSize);
|
||||||
|
localUnacknowledgesStanzas.addAll(unacknowledgedStanzas);
|
||||||
|
int droppedElements = elements.size() - overflowElementNum - 1;
|
||||||
|
|
||||||
|
String message = "The queue size " + unacknowledgesStanzasQueueSize + " is not able to fit another "
|
||||||
|
+ droppedElements + " potential stanzas type top-level stream-elements.";
|
||||||
|
return new UnacknowledgedQueueFullException(message, overflowElementNum, droppedElements, elements,
|
||||||
|
localUnacknowledgesStanzas);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1514,7 +1514,16 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
private void drainWriterQueueToUnacknowledgedStanzas() {
|
private void drainWriterQueueToUnacknowledgedStanzas() {
|
||||||
List<Element> elements = new ArrayList<>(queue.size());
|
List<Element> elements = new ArrayList<>(queue.size());
|
||||||
queue.drainTo(elements);
|
queue.drainTo(elements);
|
||||||
for (Element element : elements) {
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
|
Element element = elements.get(i);
|
||||||
|
// If the unacknowledgedStanza queue is full, then bail out with a warning message. See SMACK-844.
|
||||||
|
if (unacknowledgedStanzas.remainingCapacity() == 0) {
|
||||||
|
StreamManagementException.UnacknowledgedQueueFullException exception = StreamManagementException.UnacknowledgedQueueFullException
|
||||||
|
.newWith(i, elements, unacknowledgedStanzas);
|
||||||
|
LOGGER.log(Level.WARNING,
|
||||||
|
"Some stanzas may be lost as not all could be drained to the unacknowledged stanzas queue", exception);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (element instanceof Stanza) {
|
if (element instanceof Stanza) {
|
||||||
unacknowledgedStanzas.add((Stanza) element);
|
unacknowledgedStanzas.add((Stanza) element);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue