Skip to content

Commit 9434a44

Browse files
committed
Fix BZ 64467. Improve performance of closing idle streams
1 parent e652925 commit 9434a44

3 files changed

Lines changed: 36 additions & 9 deletions

File tree

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

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

14751475

1476-
private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception {
1477-
for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) {
1478-
Stream stream = getStream(i, false);
1479-
if (stream != null) {
1480-
stream.closeIfIdle();
1476+
private void closeIdleStreams(int newMaxActiveRemoteStreamId) {
1477+
for (Entry<Integer,Stream> entry : streams.entrySet()) {
1478+
if (entry.getKey().intValue() > maxActiveRemoteStreamId &&
1479+
entry.getKey().intValue() < newMaxActiveRemoteStreamId) {
1480+
entry.getValue().closeIfIdle();
14811481
}
14821482
}
14831483
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
@@ -147,21 +147,44 @@ public void testClientSendOldStream() throws Exception {
147147

148148
@Test
149149
public void testImplicitClose() throws Exception {
150+
doTestImplicitClose(5);
151+
}
152+
153+
154+
// https://bz.apache.org/bugzilla/show_bug.cgi?id=64467
155+
@Test
156+
public void testImplicitCloseLargeId() throws Exception {
157+
doTestImplicitClose(Integer.MAX_VALUE - 8);
158+
}
159+
160+
161+
private void doTestImplicitClose(int lastStreamId) throws Exception {
162+
163+
long startFirst = System.nanoTime();
150164
http2Connect();
165+
long durationFirst = System.nanoTime() - startFirst;
151166

152167
sendPriority(3, 0, 16);
153-
sendPriority(5, 0, 16);
168+
sendPriority(lastStreamId, 0, 16);
154169

155-
sendSimpleGetRequest(5);
170+
long startSecond = System.nanoTime();
171+
sendSimpleGetRequest(lastStreamId);
156172
readSimpleGetResponse();
157-
Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace());
173+
long durationSecond = System.nanoTime() - startSecond;
174+
175+
Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace());
158176
output.clearTrace();
159177

178+
// Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly
179+
// to allow for CI systems under load that can exhibit significant timing variation.
180+
Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" +
181+
durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3);
182+
160183
// Should trigger an error since stream 3 should have been implicitly
161184
// closed.
162185
sendSimpleGetRequest(3);
163186

164-
handleGoAwayResponse(5);
187+
handleGoAwayResponse(lastStreamId);
165188
}
166189

167190

webapps/docs/changelog.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
<update>
7272
Add support for ALPN on recent OpenJDK 8 releases. (remm)
7373
</update>
74+
<fix>
75+
<bug>64467</bug>: Improve performance of closing idle HTTP/2 streams.
76+
(markt)
77+
</fix>
7478
</changelog>
7579
</subsection>
7680
<subsection name="WebSocket">

0 commit comments

Comments
 (0)