mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-25 13:57:58 +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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.packet.Element;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
public abstract class StreamManagementException extends SmackException {
|
||||
|
@ -110,5 +113,56 @@ public abstract class StreamManagementException extends SmackException {
|
|||
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() {
|
||||
List<Element> elements = new ArrayList<>(queue.size());
|
||||
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) {
|
||||
unacknowledgedStanzas.add((Stanza) element);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue