Skip to content

Commit c8acd2a

Browse files
committed
Fix BZ 64467. Improve performance of closing idle streams
1 parent f936bbf commit c8acd2a

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

java/org/apache/coyote/http2/Http2UpgradeHandler.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,11 +1582,11 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream)
15821582
}
15831583

15841584

1585-
private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception {
1586-
for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) {
1587-
Stream stream = getStream(i, false);
1588-
if (stream != null) {
1589-
stream.closeIfIdle();
1585+
private void closeIdleStreams(int newMaxActiveRemoteStreamId) {
1586+
for (Entry<Integer,Stream> entry : streams.entrySet()) {
1587+
if (entry.getKey().intValue() > maxActiveRemoteStreamId &&
1588+
entry.getKey().intValue() < newMaxActiveRemoteStreamId) {
1589+
entry.getValue().closeIfIdle();
15901590
}
15911591
}
15921592
maxActiveRemoteStreamId = newMaxActiveRemoteStreamId;

test/org/apache/coyote/http2/TestHttp2Section_5_1.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,44 @@ public void testClientSendOldStream() throws Exception {
152152

153153
@Test
154154
public void testImplicitClose() throws Exception {
155+
doTestImplicitClose(5);
156+
}
157+
158+
159+
// https://bz.apache.org/bugzilla/show_bug.cgi?id=64467
160+
@Test
161+
public void testImplicitCloseLargeId() throws Exception {
162+
doTestImplicitClose(Integer.MAX_VALUE - 8);
163+
}
164+
165+
166+
private void doTestImplicitClose(int lastStreamId) throws Exception {
167+
168+
long startFirst = System.nanoTime();
155169
http2Connect();
170+
long durationFirst = System.nanoTime() - startFirst;
156171

157172
sendPriority(3, 0, 16);
158-
sendPriority(5, 0, 16);
173+
sendPriority(lastStreamId, 0, 16);
159174

160-
sendSimpleGetRequest(5);
175+
long startSecond = System.nanoTime();
176+
sendSimpleGetRequest(lastStreamId);
161177
readSimpleGetResponse();
162-
Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace());
178+
long durationSecond = System.nanoTime() - startSecond;
179+
180+
Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace());
163181
output.clearTrace();
164182

183+
// Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly
184+
// to allow for CI systems under load that can exhibit significant timing variation.
185+
Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" +
186+
durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3);
187+
165188
// Should trigger an error since stream 3 should have been implicitly
166189
// closed.
167190
sendSimpleGetRequest(3);
168191

169-
handleGoAwayResponse(5);
192+
handleGoAwayResponse(lastStreamId);
170193
}
171194

172195

webapps/docs/changelog.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
<update>
6464
Add support for ALPN on recent OpenJDK 8 releases. (remm)
6565
</update>
66+
<fix>
67+
<bug>64467</bug>: Improve performance of closing idle HTTP/2 streams.
68+
(markt)
69+
</fix>
6670
</changelog>
6771
</subsection>
6872
<subsection name="WebSocket">

0 commit comments

Comments
 (0)