This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 14d3637bec7708d6a359165db889b6362d03925a Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Dec 7 11:14:46 2022 +0000 Implement new allocation algorithm Currently using defaults as priorities aren't read yet. --- .../apache/coyote/http2/AbstractNonZeroStream.java | 55 +--- java/org/apache/coyote/http2/AbstractStream.java | 47 ---- java/org/apache/coyote/http2/Constants.java | 6 +- .../apache/coyote/http2/Http2UpgradeHandler.java | 310 +++++++-------------- .../apache/coyote/http2/LocalStrings.properties | 2 - .../apache/coyote/http2/LocalStrings_cs.properties | 1 - .../apache/coyote/http2/LocalStrings_es.properties | 2 - .../apache/coyote/http2/LocalStrings_fr.properties | 2 - .../apache/coyote/http2/LocalStrings_ja.properties | 2 - .../apache/coyote/http2/LocalStrings_ko.properties | 2 - .../coyote/http2/LocalStrings_zh_CN.properties | 2 - java/org/apache/coyote/http2/Stream.java | 24 +- 12 files changed, 129 insertions(+), 326 deletions(-) diff --git a/java/org/apache/coyote/http2/AbstractNonZeroStream.java b/java/org/apache/coyote/http2/AbstractNonZeroStream.java index 0876fc88c6..5a9c3e3a48 100644 --- a/java/org/apache/coyote/http2/AbstractNonZeroStream.java +++ b/java/org/apache/coyote/http2/AbstractNonZeroStream.java @@ -17,7 +17,6 @@ package org.apache.coyote.http2; import java.nio.ByteBuffer; -import java.util.Iterator; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -36,8 +35,6 @@ abstract class AbstractNonZeroStream extends AbstractStream { protected final StreamStateMachine state; - private volatile int weight = Constants.DEFAULT_WEIGHT; - AbstractNonZeroStream(String connectionId, Integer identifier) { super(identifier); @@ -51,12 +48,6 @@ abstract class AbstractNonZeroStream extends AbstractStream { } - @Override - final int getWeight() { - return weight; - } - - /* * General method used when reprioritising a stream and care needs to be * taken not to create circular references. @@ -71,27 +62,7 @@ abstract class AbstractNonZeroStream extends AbstractStream { parent.getIdAsString(), Integer.toString(weight))); } - // Check if new parent is a descendant of this stream - if (isDescendant(parent)) { - parent.detachFromParent(); - // Cast is always safe since any descendant of this stream must be - // an instance of AbstractNonZeroStream - getParentStream().addChild((AbstractNonZeroStream) parent); - } - - if (exclusive) { - // Need to move children of the new parent to be children of this - // stream. Slightly convoluted to avoid concurrent modification. - Iterator<AbstractNonZeroStream> parentsChildren = parent.getChildStreams().iterator(); - while (parentsChildren.hasNext()) { - AbstractNonZeroStream parentsChild = parentsChildren.next(); - parentsChildren.remove(); - this.addChild(parentsChild); - } - } - detachFromParent(); - parent.addChild(this); - this.weight = weight; + // TODO } @@ -109,29 +80,7 @@ abstract class AbstractNonZeroStream extends AbstractStream { parent.getIdAsString(), Integer.toString(weight))); } - parent.addChild(this); - this.weight = weight; - } - - - /* - * Used when "recycling" a stream and replacing a Stream instance with a - * RecycledStream instance. - * - * Replace this stream with the provided stream in the parent/child - * hierarchy. - * - * Changes to the priority tree need to be synchronized at the connection - * level. This is the caller's responsibility. - */ - void replaceStream(AbstractNonZeroStream replacement) { - getParentStream().addChild(replacement); - detachFromParent(); - for (AbstractNonZeroStream child : getChildStreams()) { - replacement.addChild(child); - } - getChildStreams().clear(); - replacement.weight = weight; + // TODO } diff --git a/java/org/apache/coyote/http2/AbstractStream.java b/java/org/apache/coyote/http2/AbstractStream.java index dc651d30e9..d3533c5bd8 100644 --- a/java/org/apache/coyote/http2/AbstractStream.java +++ b/java/org/apache/coyote/http2/AbstractStream.java @@ -16,9 +16,6 @@ */ package org.apache.coyote.http2; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; @@ -35,8 +32,6 @@ abstract class AbstractStream { private final Integer identifier; private final String idAsString; - private volatile AbstractStream parentStream = null; - private final Set<AbstractNonZeroStream> childStreams = ConcurrentHashMap.newKeySet(); private long windowSize = ConnectionSettingsBase.DEFAULT_INITIAL_WINDOW_SIZE; private volatile int connectionAllocationRequested = 0; @@ -64,46 +59,6 @@ abstract class AbstractStream { } - final void detachFromParent() { - if (parentStream != null) { - parentStream.getChildStreams().remove(this); - parentStream = null; - } - } - - - final void addChild(AbstractNonZeroStream child) { - child.setParentStream(this); - childStreams.add(child); - } - - - final boolean isDescendant(AbstractStream stream) { - // Is the passed in Stream a descendant of this Stream? - // Start at the passed in Stream and work up - AbstractStream parent = stream.getParentStream(); - while (parent != null && parent != this) { - parent = parent.getParentStream(); - } - return parent != null; - } - - - final AbstractStream getParentStream() { - return parentStream; - } - - - final void setParentStream(AbstractStream parentStream) { - this.parentStream = parentStream; - } - - - final Set<AbstractNonZeroStream> getChildStreams() { - return childStreams; - } - - final synchronized void setWindowSize(long windowSize) { this.windowSize = windowSize; } @@ -181,6 +136,4 @@ abstract class AbstractStream { abstract String getConnectionId(); - - abstract int getWeight(); } diff --git a/java/org/apache/coyote/http2/Constants.java b/java/org/apache/coyote/http2/Constants.java index 739ae7eb12..e1ee63bb34 100644 --- a/java/org/apache/coyote/http2/Constants.java +++ b/java/org/apache/coyote/http2/Constants.java @@ -19,7 +19,11 @@ package org.apache.coyote.http2; public class Constants { // Prioritisation - public static final int DEFAULT_WEIGHT = 16; + public static final int DEFAULT_URGENCY = 3; + public static final boolean DEFAULT_INCREMENTAL = false; + // Range 0 to 7 inclusive + public static final int URGENCY_RANGE = 8; + // Parsing static final int DEFAULT_HEADER_READ_BUFFER_SIZE = 1024; diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java index a2405994a8..a5ebde3b26 100644 --- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java +++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java @@ -20,15 +20,15 @@ import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.Queue; import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -94,8 +94,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH private static final HeaderSink HEADER_SINK = new HeaderSink(); - private final Object priorityTreeLock = new Object(); - protected final String connectionId; protected final Http2Protocol protocol; @@ -131,7 +129,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH private final AtomicInteger nextLocalStreamId = new AtomicInteger(2); private final PingManager pingManager = getPingManager(); private volatile int newStreamsSinceLastPrune = 0; - private final Set<AbstractStream> backLogStreams = ConcurrentHashMap.newKeySet(); + private final Set<Stream> backLogStreams = new HashSet<>(); private long backLogSize = 0; // The time at which the connection will timeout unless data arrives before // then. -1 means no timeout. @@ -954,11 +952,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH stream.setConnectionAllocationRequested(reservation); backLogSize += reservation; backLogStreams.add(stream); - // Add the parents as well - AbstractStream parent = stream.getParentStream(); - while (parent != null && backLogStreams.add(parent)) { - parent = parent.getParentStream(); - } } } else if (windowSize < reservation) { allocation = (int) windowSize; @@ -1070,8 +1063,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH private synchronized Set<AbstractStream> releaseBackLog(int increment) throws Http2Exception { Set<AbstractStream> result = new HashSet<>(); - int remaining = increment; - if (backLogSize < remaining) { + if (backLogSize < increment) { // Can clear the whole backlog for (AbstractStream stream : backLogStreams) { if (stream.getConnectionAllocationRequested() > 0) { @@ -1079,23 +1071,90 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH stream.setConnectionAllocationRequested(0); } } - remaining -= backLogSize; + // Cast is safe due to test above + int remaining = increment - (int) backLogSize; backLogSize = 0; super.incrementWindowSize(remaining); result.addAll(backLogStreams); backLogStreams.clear(); } else { - allocate(this, remaining); - Iterator<AbstractStream> streamIter = backLogStreams.iterator(); - while (streamIter.hasNext()) { - AbstractStream stream = streamIter.next(); - if (stream.getConnectionAllocationMade() > 0) { - backLogSize -= stream.getConnectionAllocationMade(); - backLogSize -= stream.getConnectionAllocationRequested(); - stream.setConnectionAllocationRequested(0); - result.add(stream); - streamIter.remove(); + // Can't clear the whole backlog. + // Need streams in priority order + Set<Stream> orderedStreams = new ConcurrentSkipListSet<>(Comparator.comparingInt(Stream::getUrgency) + .thenComparing(Stream::getIncremental).thenComparing(Stream::getIdAsInt)); + orderedStreams.addAll(backLogStreams); + + // Iteration 1. Need to work out how much we can clear. + long urgencyWhereAllocationIsExhausted = 0; + long requestedAllocationForIncrementalStreams = 0; + int remaining = increment; + Iterator<Stream> orderedStreamsIterator = orderedStreams.iterator(); + while (orderedStreamsIterator.hasNext()) { + Stream s = orderedStreamsIterator.next(); + if (urgencyWhereAllocationIsExhausted < s.getUrgency()) { + if (remaining < 1) { + break; + } + requestedAllocationForIncrementalStreams = 0; + } + urgencyWhereAllocationIsExhausted = s.getUrgency(); + if (s.getIncremental()) { + requestedAllocationForIncrementalStreams += s.getConnectionAllocationRequested(); + remaining -= s.getConnectionAllocationRequested(); + } else { + remaining -= s.getConnectionAllocationRequested(); + if (remaining < 1) { + break; + } + } + } + + // Iteration 2. Allocate. + // Reset for second iteration + remaining = increment; + orderedStreamsIterator = orderedStreams.iterator(); + while (orderedStreamsIterator.hasNext()) { + Stream s = orderedStreamsIterator.next(); + if (s.getUrgency() < urgencyWhereAllocationIsExhausted) { + // Can fully allocate + remaining = allocate(s, remaining); + result.add(s); + orderedStreamsIterator.remove(); + backLogStreams.remove(s); + } else if (requestedAllocationForIncrementalStreams == 0) { + // Allocation ran out in non-incremental streams so fully + // allocate in iterator order until allocation is exhausted + remaining = allocate(s, remaining); + result.add(s); + if (s.getConnectionAllocationRequested() == 0) { + // Fully allocated + orderedStreamsIterator.remove(); + backLogStreams.remove(s); + } + if (remaining < 1) { + break; + } + } else { + // Allocation ran out in incremental streams. Distribute + // remaining allocation between the incremental streams at + // this urgency level. + if (s.getUrgency() != urgencyWhereAllocationIsExhausted) { + break; + } + + int share = (int) (s.getConnectionAllocationRequested() * remaining / requestedAllocationForIncrementalStreams); + if (share == 0) { + share = 1; + } + allocate(s, share); + result.add(s); + if (s.getConnectionAllocationRequested() == 0) { + // Fully allocated (unlikely but possible due to + // rounding if only a few bytes required). + orderedStreamsIterator.remove(); + backLogStreams.remove(s); + } } } } @@ -1123,67 +1182,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH leftToAllocate = leftToAllocate - allocatedThisTime; } - if (leftToAllocate == 0) { - return 0; - } - if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.allocate.left", getConnectionId(), stream.getIdAsString(), Integer.toString(leftToAllocate))); } - // Recipients are children of the current stream that are in the - // backlog. - Set<AbstractStream> recipients = new HashSet<>(stream.getChildStreams()); - recipients.retainAll(backLogStreams); - - // Loop until we run out of allocation or recipients - while (leftToAllocate > 0) { - if (recipients.size() == 0) { - if (stream.getConnectionAllocationMade() == 0) { - backLogStreams.remove(stream); - } - if (stream.getIdAsInt() == 0) { - throw new IllegalStateException(); - } - return leftToAllocate; - } - - int totalWeight = 0; - for (AbstractStream recipient : recipients) { - if (log.isDebugEnabled()) { - log.debug(sm.getString("upgradeHandler.allocate.recipient", - getConnectionId(), stream.getIdAsString(), recipient.getIdAsString(), - Integer.toString(recipient.getWeight()))); - } - totalWeight += recipient.getWeight(); - } - - // Use an Iterator so fully allocated children/recipients can be - // removed. - Iterator<AbstractStream> iter = recipients.iterator(); - int allocated = 0; - while (iter.hasNext()) { - AbstractStream recipient = iter.next(); - int share = leftToAllocate * recipient.getWeight() / totalWeight; - if (share == 0) { - // This is to avoid rounding issues triggering an infinite - // loop. It will cause a very slight over allocation but - // HTTP/2 should cope with that. - share = 1; - } - int remainder = allocate(recipient, share); - // Remove recipients that receive their full allocation so that - // they are excluded from the next allocation round. - if (remainder > 0) { - iter.remove(); - } - allocated += (share - remainder); - } - leftToAllocate -= allocated; - } - - return 0; + return leftToAllocate; } @@ -1289,7 +1293,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH // maximum number of concurrent streams. long max = localSettings.getMaxConcurrentStreams(); - // Only need ~+10% for streams that are in the priority tree, // Ideally need to retain information for a "significant" amount of time // after sending END_STREAM (RFC 7540, page 20) so we detect potential // connection error. 5x seems reasonable. The client will have had @@ -1307,100 +1310,23 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH } int toClose = size - (int) max; - if (toClose < 1) { - return; - } - // Need to try and close some streams. - // Try to close streams in this order - // 1. Completed streams used for a request with no children - // 2. Completed streams used for a request with children - // 3. Closed final streams - // - // The pruning halts as soon as enough streams have been pruned. - - // Use these sets to track the different classes of streams - TreeSet<Integer> candidatesStepTwo = new TreeSet<>(); - TreeSet<Integer> candidatesStepThree = new TreeSet<>(); - - // Step 1 - // Iterator is in key order so we automatically have the oldest streams - // first - // Tests depend on parent/child relationship between streams so need to - // lock on priorityTreeLock to ensure a consistent view. - synchronized (priorityTreeLock) { - for (AbstractNonZeroStream stream : streams.values()) { - // Never remove active streams - if (stream instanceof Stream && ((Stream) stream).isActive()) { - continue; - } - - if (stream.isClosedFinal()) { - // This stream went from IDLE to CLOSED and is likely to have - // been created by the client as part of the priority tree. - // Candidate for step 3. - candidatesStepThree.add(stream.getIdentifier()); - } else if (stream.getChildStreams().size() == 0) { - // Prune it - AbstractStream parent = stream.getParentStream(); - streams.remove(stream.getIdentifier()); - stream.detachFromParent(); - if (log.isDebugEnabled()) { - log.debug(sm.getString("upgradeHandler.pruned", connectionId, stream.getIdAsString())); - } - if (--toClose < 1) { - return; - } - - // If removing this child made the parent childless then see if - // the parent can be removed. - // Don't try and remove Stream 0 as that is the connection - // Don't try and remove 'newer' streams. We'll get to them as we - // work through the ordered list of streams. - while (toClose > 0 && parent.getIdAsInt() > 0 && parent.getIdAsInt() < stream.getIdAsInt() && - parent.getChildStreams().isEmpty()) { - // This cast is safe since we know parent ID > 0 therefore - // this isn't the connection - stream = (AbstractNonZeroStream) parent; - parent = stream.getParentStream(); - streams.remove(stream.getIdentifier()); - stream.detachFromParent(); - if (log.isDebugEnabled()) { - log.debug(sm.getString("upgradeHandler.pruned", connectionId, stream.getIdAsString())); - } - if (--toClose < 1) { - return; - } - // Also need to remove this stream from the step 2 list - candidatesStepTwo.remove(stream.getIdentifier()); - } - } else { - // Closed, with children. Candidate for step 2. - candidatesStepTwo.add(stream.getIdentifier()); - } - } - } - - // Process the P2 list - for (Integer streamIdToRemove : candidatesStepTwo) { - removeStreamFromPriorityTree(streamIdToRemove); - if (log.isDebugEnabled()) { - log.debug(sm.getString("upgradeHandler.pruned", connectionId, streamIdToRemove)); - } - if (--toClose < 1) { + // Need to try and prune some streams. Prune streams starting with the + // oldest. Pruning stops as soon as enough streams have been pruned. + // Iterator is in key order. + for (AbstractNonZeroStream stream : streams.values()) { + if (toClose < 1) { return; } - } - - while (toClose > 0 && candidatesStepThree.size() > 0) { - Integer streamIdToRemove = candidatesStepThree.pollLast(); - removeStreamFromPriorityTree(streamIdToRemove); - if (log.isDebugEnabled()) { - log.debug(sm.getString("upgradeHandler.prunedPriority", connectionId, streamIdToRemove)); + if (stream instanceof Stream && ((Stream) stream).isActive()) { + continue; } - if (--toClose < 1) { - return; + streams.remove(stream.getIdentifier()); + toClose--; + if (log.isDebugEnabled()) { + log.debug(sm.getString("upgradeHandler.pruned", connectionId, stream.getIdAsString())); } + } if (toClose > 0) { @@ -1410,33 +1336,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH } - private void removeStreamFromPriorityTree(Integer streamIdToRemove) { - synchronized (priorityTreeLock) { - AbstractNonZeroStream streamToRemove = streams.remove(streamIdToRemove); - // Move the removed Stream's children to the removed Stream's - // parent. - Set<AbstractNonZeroStream> children = streamToRemove.getChildStreams(); - if (children.size() == 1) { - // Shortcut - children.iterator().next().rePrioritise( - streamToRemove.getParentStream(), streamToRemove.getWeight()); - } else { - int totalWeight = 0; - for (AbstractNonZeroStream child : children) { - totalWeight += child.getWeight(); - } - for (AbstractNonZeroStream child : children) { - children.iterator().next().rePrioritise( - streamToRemove.getParentStream(), - streamToRemove.getWeight() * child.getWeight() / totalWeight); - } - } - streamToRemove.detachFromParent(); - children.clear(); - } - } - - void push(Request request, Stream associatedStream) throws IOException { if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) { // If there are too many open streams, simply ignore the push @@ -1471,12 +1370,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH } - @Override - protected final int getWeight() { - return 0; - } - - private void reduceOverheadCount(FrameType frameType) { // A non-overhead frame reduces the overhead count by // Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR. A simple browser @@ -1909,15 +1802,10 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH void replaceStream(AbstractNonZeroStream original, AbstractNonZeroStream replacement) { - synchronized (priorityTreeLock) { - AbstractNonZeroStream current = streams.get(original.getIdentifier()); - // Might already have been recycled or removed from the priority - // tree entirely. Only replace it if the full stream is still in the - // priority tree. - if (current instanceof Stream) { - streams.put(original.getIdentifier(), replacement); - original.replaceStream(replacement); - } + AbstractNonZeroStream current = streams.get(original.getIdentifier()); + // Only replace the stream if it currently uses the full implementation. + if (current instanceof Stream) { + streams.put(original.getIdentifier(), replacement); } } diff --git a/java/org/apache/coyote/http2/LocalStrings.properties b/java/org/apache/coyote/http2/LocalStrings.properties index 547a1880d1..3670d60f42 100644 --- a/java/org/apache/coyote/http2/LocalStrings.properties +++ b/java/org/apache/coyote/http2/LocalStrings.properties @@ -127,7 +127,6 @@ streamStateMachine.invalidFrame=Connection [{0}], Stream [{1}], State [{2}], Fra upgradeHandler.allocate.debug=Connection [{0}], Stream [{1}], allocated [{2}] bytes upgradeHandler.allocate.left=Connection [{0}], Stream [{1}], [{2}] bytes unallocated - trying to allocate to children -upgradeHandler.allocate.recipient=Connection [{0}], Stream [{1}], potential recipient [{2}] with weight [{3}] upgradeHandler.connectionError=Connection error upgradeHandler.fallToDebug=\n\ \ Note: further occurrences of HTTP/2 stream errors will be logged at DEBUG level. @@ -144,7 +143,6 @@ upgradeHandler.prefaceReceived=Connection [{0}], Connection preface received fro upgradeHandler.pruneIncomplete=Connection [{0}], Stream [{1}], Failed to fully prune the connection because there are [{2}] too many active streams upgradeHandler.pruneStart=Connection [{0}] Starting pruning of old streams. Limit is [{1}] and there are currently [{2}] streams. upgradeHandler.pruned=Connection [{0}] Pruned completed stream [{1}] -upgradeHandler.prunedPriority=Connection [{0}] Pruned unused stream [{1}] that may have been part of the priority tree upgradeHandler.releaseBacklog=Connection [{0}], Stream [{1}] released from backlog upgradeHandler.reset.receive=Connection [{0}], Stream [{1}], Reset received due to [{2}] upgradeHandler.enableRfc7450Priorities=Connection [{0}], RFC 7450 priorities may not be enabled after being disabled in the initial connection settings frame (see RFC 9218) diff --git a/java/org/apache/coyote/http2/LocalStrings_cs.properties b/java/org/apache/coyote/http2/LocalStrings_cs.properties index 88e888b023..b07e9902d1 100644 --- a/java/org/apache/coyote/http2/LocalStrings_cs.properties +++ b/java/org/apache/coyote/http2/LocalStrings_cs.properties @@ -31,7 +31,6 @@ http2Parser.processFramePushPromise=Connection [{0}], Stream [{1}], Rámec pro P upgradeHandler.pingFailed=Spojení [{0}] pro odeslání příkazu ping na klienta selhalo upgradeHandler.prefaceReceived=Spojení [{0}], přírava spojení přijata od klienta upgradeHandler.pruneIncomplete=Plné omezení spojení [{0}] selhalo, neboť streamy byly aktivní / použité v prioritním stromu. Existuje [{2}] příliš mnoho streamů -upgradeHandler.prunedPriority=Spojení [{0}] omezilo nepoužívaný stream [{1}], který mohl být částí prioritního stromu upgradeHandler.rst.debug=Spojení [{0}], Stream [{1}], Chyba [{2}], Zpráva [{3}], RST (zavírání streamu) upgradeHandler.sendPrefaceFail=Spojení [{0}], selhalo odeslánízahájení klientovi upgradeHandler.socketCloseFailed=Chyba zavírání socketu diff --git a/java/org/apache/coyote/http2/LocalStrings_es.properties b/java/org/apache/coyote/http2/LocalStrings_es.properties index acd5243110..2664cc5f8c 100644 --- a/java/org/apache/coyote/http2/LocalStrings_es.properties +++ b/java/org/apache/coyote/http2/LocalStrings_es.properties @@ -44,12 +44,10 @@ streamProcessor.error.connection=Conexión [{0}], Flujo [{1}], Ha ocurrido un er streamStateMachine.debug.change=Conexión [{0}], Flujo [{1}], Estado cambió de [{2}] a [{3}] upgradeHandler.allocate.left=Conexión [{0}], Flujo [{1}], [{2}] bytes no asignados - tratando de asignar en el hijo -upgradeHandler.allocate.recipient=Conexión [{0}], Flujo [{1}], recipiente potencial [{2}] con peso [{3}] upgradeHandler.ioerror=Conexión [{0}] upgradeHandler.pingFailed=Conexión [{0}] falló al hacer ping al cliente upgradeHandler.prefaceReceived=Conexión [{0}], Pre face de conexión recibida del cliente\n upgradeHandler.pruneIncomplete=La conexión [{0}] Falló al podar completamente la conexión porque existen flujos activos / usados en el árbol de priorida. Existen [{2}] muchos flujos -upgradeHandler.prunedPriority=La conexión [{0}] ha cortado el flujo en desuso [{1}] el cual podía ser parte del árbol prioritario upgradeHandler.rst.debug=Conexión [{0}], Flujo [{1}], Error [{2}], Mensaje [{3}], RST (cerrando flujo) upgradeHandler.sendPrefaceFail=La conexión [{0}], Falló al enviar el prefacio al cliente\n upgradeHandler.socketCloseFailed=Error cerrando el socket diff --git a/java/org/apache/coyote/http2/LocalStrings_fr.properties b/java/org/apache/coyote/http2/LocalStrings_fr.properties index e8551e4370..9044d4f47f 100644 --- a/java/org/apache/coyote/http2/LocalStrings_fr.properties +++ b/java/org/apache/coyote/http2/LocalStrings_fr.properties @@ -126,7 +126,6 @@ streamStateMachine.invalidFrame=Connection [{0}], Flux [{1}], Etat [{2}], Type d upgradeHandler.allocate.debug=Connection [{0}], Flux [{1}], [{2}] octets alloués upgradeHandler.allocate.left=Connection [{0}], Flux [{1}], [{2}] octets désalloués, essai d''allocation aux enfants -upgradeHandler.allocate.recipient=Connection [{0}], Flux [{1}], receveur potentiel [{2}] avec poids [{3}] upgradeHandler.connectionError=Erreur de la connection upgradeHandler.fallToDebug=\n\ \ Note: les occurrences suivantes d'erreurs de stream HTTP/2 seront enregistrées au niveau DEBUG. @@ -143,7 +142,6 @@ upgradeHandler.prefaceReceived=Connection [{0}], préface de la connection recue upgradeHandler.pruneIncomplete=Connexion [{0}], Flux [{1}], Erreur lors de l''élimination complète de la connexion parce que des flux sont encore actifs / utilisés dans l''arbre de priorité, il y a [{2}] flux en trop upgradeHandler.pruneStart=Connection [{0}] Début de l''élimination des anciens flux, la limite est de [{1}] et il y a actuellement [{2}] flux upgradeHandler.pruned=Connection [{0}] Elimination du flux terminé [{1}] -upgradeHandler.prunedPriority=La connexion [{0}] a élagué le flux inutilisé [{1}] qui faisait peut-être partie de l''arbre de priorité upgradeHandler.releaseBacklog=Connection [{0}], Flux [{1}] enlevée de la file d''attente upgradeHandler.reset.receive=Connection [{0}], Stream [{1}], Reset a été reçu à cause de [{2}] upgradeHandler.rst.debug=Connexion [{0}], Flux [{1}], Erreur [{2}], Message [{3}], RST (fermeture du flux) diff --git a/java/org/apache/coyote/http2/LocalStrings_ja.properties b/java/org/apache/coyote/http2/LocalStrings_ja.properties index b0e237d260..a9b7b8b59d 100644 --- a/java/org/apache/coyote/http2/LocalStrings_ja.properties +++ b/java/org/apache/coyote/http2/LocalStrings_ja.properties @@ -126,7 +126,6 @@ streamStateMachine.invalidFrame=コネクション [{0}]、ストリーム [{1}] upgradeHandler.allocate.debug=コネクション [{0}]、ストリーム [{1}]、割り当てられた [{2}] バイト upgradeHandler.allocate.left=コネクション [{0}]、ストリーム [{1}]、[{2}] バイトが未割り当て - 子への割り当てを試みています -upgradeHandler.allocate.recipient=コネクション [{0}]、ストリーム [{1}]、重み [{3}] の潜在的な受信者 [{2}] upgradeHandler.connectionError=接続エラー upgradeHandler.fallToDebug=注: HTTP/2 ストリームのエラーがさらに発生すると、DEBUG レベルでログに記録されます。 upgradeHandler.goaway.debug=コネクション [{0}]、Goaway、最終ストリーム [{1}]、エラーコード [{2}]、デバッグデータ [{3}] @@ -142,7 +141,6 @@ upgradeHandler.prefaceReceived=コネクション [{0}]、クライアントか upgradeHandler.pruneIncomplete=コネクション [{0}]、ストリーム [{1}]、コネクションを削除できませんでした。アクティブなストリーム数 [{2}] は多すぎます。 upgradeHandler.pruneStart=コネクション [{0}] 古いストリームのプルーニングを開始します。 上限は [{1}] で、現在 [{2}] ストリームがあります。 upgradeHandler.pruned=コネクション [{0}]、完了したストリーム [{1}] は削除します。 -upgradeHandler.prunedPriority=コネクション [{0}]、優先度木に登録されていた可能性のある未使用のストリーム [{1}] を取り除きました。 upgradeHandler.releaseBacklog=コネクション [{0}]、ストリーム [{1}] はバックログから解放されました upgradeHandler.reset.receive=Connection[{0}]、Stream[{1}]、[{2}]のためにリセットを受信しました upgradeHandler.rst.debug=コネクション [{0}]、ストリーム [{1}]、エラー [{2}]、メッセージ [{3}]、RST (ストリームを切断します) diff --git a/java/org/apache/coyote/http2/LocalStrings_ko.properties b/java/org/apache/coyote/http2/LocalStrings_ko.properties index e8b1825382..a8adb1f976 100644 --- a/java/org/apache/coyote/http2/LocalStrings_ko.properties +++ b/java/org/apache/coyote/http2/LocalStrings_ko.properties @@ -125,7 +125,6 @@ streamStateMachine.invalidFrame=연결 [{0}], 스트림 [{1}], 상태 [{2}], 프 upgradeHandler.allocate.debug=연결 [{0}], 스트림 [{1}], [{2}] 바이트를 할당함. upgradeHandler.allocate.left=연결 [{0}], 스트림 [{1}], [{2}] 바이트들이 할당 해제되었습니다 - 자식들에 할당하려 시도합니다. -upgradeHandler.allocate.recipient=연결 [{0}], 스트림 [{1}], 가중치 [{3}]의 잠재적 수신자 [{2}] upgradeHandler.connectionError=연결 오류 upgradeHandler.goaway.debug=연결 [{0}], Goaway, 마지막 스트림 [{1}], 오류 코드 [{2}], 디버그 데이터 [{3}] upgradeHandler.init=연결 [{0}], 상태 [{1}] @@ -140,7 +139,6 @@ upgradeHandler.prefaceReceived=연결 [{0}]: 연결 preface를 클라이언트 upgradeHandler.pruneIncomplete=연결 [{0}]: 스트림들이 Priority tree에서 활성화되어 있거나 사용되고 있기 때문에, 해당 연결을 완전히 제거하지 못했습니다. 너무 많은 스트림들이 존재합니다: [{2}]. upgradeHandler.pruneStart=연결 [{0}]: 이전 스트림들에 대한 가지치기를 시작합니다. 한계값은 [{1}] 이고, 현재 [{2}]개의 스트림들이 존재합니다. upgradeHandler.pruned=연결 [{0}]이(가) 완료된 스트림 [{1}]을(를) 제거했습니다. -upgradeHandler.prunedPriority=연결 [{0}]이(가) 사용되지 않는 스트림 [{1}]을(를) 제거합니다. 해당 스트림은 priority tree의 일부였을 수 있습니다. upgradeHandler.releaseBacklog=연결 [{0}], 스트림 [{1}]이(가) 백로그로부터 해제되었습니다. upgradeHandler.reset.receive=연결 [{0}], 스트림 [{1}], [{2}](으)로 인해 리셋을 수신했습니다. upgradeHandler.rst.debug=연결 [{0}], 스트림 [{1}], 오류 [{2}], 메시지 [{3}], RST (스트림을 닫습니다) diff --git a/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties b/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties index d0713e931a..ec4c7612ba 100644 --- a/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties +++ b/java/org/apache/coyote/http2/LocalStrings_zh_CN.properties @@ -126,7 +126,6 @@ streamStateMachine.invalidFrame=连接{0}、流{1}、状态{2}、帧类型{3} upgradeHandler.allocate.debug=连接[{0}],流[{1}],已分配[{2}]字节 upgradeHandler.allocate.left=连接[{0}],流[{1}],[{2}]字节未分配 - 尝试分配给子项 -upgradeHandler.allocate.recipient=(:连接[{0}],流[{1}],潜在接收者[{2}],权重为[{3}] upgradeHandler.connectionError=连接错误 upgradeHandler.goaway.debug=连接[{0}],离开,最后的流[{1}],错误码[{2}],调试数据[{3}] upgradeHandler.init=连接[{0}],状态[{1}] @@ -141,7 +140,6 @@ upgradeHandler.prefaceReceived=连接[{0}],从客户端收到连接准备。 upgradeHandler.pruneIncomplete=连接[{0}],流[{1}],无法完全修剪连接,因为有[{2}]个活动流太多 upgradeHandler.pruneStart=连接[{0}]正在开始修剪旧流。限制为[{1}],当前有[{2}]个流。 upgradeHandler.pruned=连接[{0}]已修剪完成的流[{1}] -upgradeHandler.prunedPriority=连接[{0}]已经成为了属于优先级树中未使用的流[{1}] upgradeHandler.releaseBacklog=连接[{0}],流[{1}]已从待办事项列表中释放 upgradeHandler.reset.receive=连接[{0}],流[{1}],由于[{2}]而重置 upgradeHandler.rst.debug=连接[{0}],流[{1}],错误[{2}],消息[{3}],RST(关闭流) diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java index 53850fc384..f255029993 100644 --- a/java/org/apache/coyote/http2/Stream.java +++ b/java/org/apache/coyote/http2/Stream.java @@ -95,6 +95,9 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { private Object pendingWindowUpdateForStreamLock = new Object(); private int pendingWindowUpdateForStream = 0; + private volatile int urgency = Constants.DEFAULT_URGENCY; + private volatile boolean incremental = Constants.DEFAULT_INCREMENTAL; + Stream(Integer identifier, Http2UpgradeHandler handler) { this(identifier, handler, null); @@ -104,7 +107,6 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { Stream(Integer identifier, Http2UpgradeHandler handler, Request coyoteRequest) { super(handler.getConnectionId(), identifier); this.handler = handler; - handler.addChild(this); setWindowSize(handler.getRemoteSettings().getInitialWindowSize()); if (coyoteRequest == null) { // HTTP/2 new request @@ -833,6 +835,26 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { } + public int getUrgency() { + return urgency; + } + + + public void setUrgency(int urgency) { + this.urgency = urgency; + } + + + public boolean getIncremental() { + return incremental; + } + + + public void setIncremental(boolean incremental) { + this.incremental = incremental; + } + + class StreamOutputBuffer implements HttpOutputBuffer, WriteBuffer.Sink { private final ByteBuffer buffer = ByteBuffer.allocate(8 * 1024); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org