483878 - Parallel requests stuck via the http client transport over HTTP/2.

Fixed by recycling correctly the blockBuffer.
This commit is contained in:
Simone Bordet 2015-12-09 11:56:26 +01:00
parent c5e56e72e6
commit 35da4a3c54
2 changed files with 43 additions and 32 deletions

View File

@ -75,7 +75,12 @@ public class HeaderBlockParser
MetaData result = hpackDecoder.decode(toDecode);
buffer.limit(limit);
byteBufferPool.release(blockBuffer);
if (blockBuffer != null)
{
byteBufferPool.release(blockBuffer);
blockBuffer = null;
}
return result;
}

View File

@ -114,41 +114,47 @@ public class HeadersGenerateParseTest
}
}, 4096, 8192);
int streamId = 13;
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
PriorityFrame priorityFrame = new PriorityFrame(streamId, 3 * streamId, 200, true);
generator.generateHeaders(lease, streamId, metaData, priorityFrame, true);
for (ByteBuffer buffer : lease.getByteBuffers())
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
while (buffer.hasRemaining())
int streamId = 13;
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP, new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
PriorityFrame priorityFrame = new PriorityFrame(streamId, 3 * streamId, 200, true);
generator.generateHeaders(lease, streamId, metaData, priorityFrame, true);
frames.clear();
for (ByteBuffer buffer : lease.getByteBuffers())
{
parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
buffer = buffer.slice();
while (buffer.hasRemaining())
{
parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
}
}
}
Assert.assertEquals(1, frames.size());
HeadersFrame frame = frames.get(0);
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertTrue(frame.isEndStream());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);
Assert.assertTrue(request.getFields().contains(field));
Assert.assertEquals(1, frames.size());
HeadersFrame frame = frames.get(0);
Assert.assertEquals(streamId, frame.getStreamId());
Assert.assertTrue(frame.isEndStream());
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);
Assert.assertTrue(request.getFields().contains(field));
}
PriorityFrame priority = frame.getPriority();
Assert.assertNotNull(priority);
Assert.assertEquals(priorityFrame.getStreamId(), priority.getStreamId());
Assert.assertEquals(priorityFrame.getParentStreamId(), priority.getParentStreamId());
Assert.assertEquals(priorityFrame.getWeight(), priority.getWeight());
Assert.assertEquals(priorityFrame.isExclusive(), priority.isExclusive());
}
PriorityFrame priority = frame.getPriority();
Assert.assertNotNull(priority);
Assert.assertEquals(priorityFrame.getStreamId(), priority.getStreamId());
Assert.assertEquals(priorityFrame.getParentStreamId(), priority.getParentStreamId());
Assert.assertEquals(priorityFrame.getWeight(), priority.getWeight());
Assert.assertEquals(priorityFrame.isExclusive(), priority.isExclusive());
}
}