Source:
<code>void maybeReadPayload(ChannelHandlerContext ctx) { if (pending.readableBytes() < nextFrameSize) { return; } ByteBuf payload = ctx.alloc().buffer(nextFrameSize); pending.readBytes(payload, nextFrameSize); state = ReadState.HEADER; HttpRequest request = HttpRequest.of( THRIFT_HEADERS.toMutable(), new ByteBufHttpData(payload, true)); ServiceRequestContext requestContext = ServiceRequestContextBuilder.of(request) .service(scribeService) .build(); final HttpResponse response; try { response = scribeService.serve(requestContext, request); } catch (Exception e) { logger.warn("Unexpected exception servicing thrift request. " + "This usually indicates a bug in armeria's thrift implementation.", e); exceptionCaught(ctx, e); return; } response.aggregateWithPooledObjects(ctx.executor(), ctx.alloc()).handle((msg, t) -> { if (t != null) { logger.warn("Unexpected exception reading thrift response. " <START> + "This usually indicates a bug in armeria's thrift implementation.", t); <END> exceptionCaught(ctx, t); return null; } HttpData content = msg.content(); final ByteBuf returned = ctx.alloc().buffer(msg.content().length() + 4); returned.writeInt(msg.content().length()); if (content instanceof ByteBufHolder) { ByteBuf buf = ((ByteBufHolder) content).content(); try { returned.writeBytes(((ByteBufHolder) content).content()); } finally { buf.release(); } } else { returned.writeBytes(content.array(), content.offset(), content.length()); } ctx.writeAndFlush(returned); return null; }); }</code><technical_language>Hmm, really? I aggregation fail other cases OOME</technical_language>

Target:
void maybeReadPayload(ChannelHandlerContext ctx) { if (pending.readableBytes() < nextFrameSize) { return; } ByteBuf payload = ctx.alloc().buffer(nextFrameSize); pending.readBytes(payload, nextFrameSize); pending.discardSomeReadBytes(); state = ReadState.HEADER; HttpRequest request = HttpRequest.of( THRIFT_HEADERS.toMutable(), new ByteBufHttpData(payload, true)); ServiceRequestContextBuilder requestContextBuilder = ServiceRequestContextBuilder.of(request) .service(scribeService) .alloc(ctx.alloc()); if (ctx.executor() instanceof EventLoop) { requestContextBuilder.eventLoop((EventLoop) ctx.executor()); } ServiceRequestContext requestContext = requestContextBuilder.build(); final HttpResponse response; try (SafeCloseable unused = requestContext.push()){ response = scribeService.serve(requestContext, request); } catch (Exception e) { exceptionCaught(ctx, e); return; } int responseIndex = nextResponseIndex++; response.aggregateWithPooledObjects(ctx.executor(), ctx.alloc()).handle((msg, t) -> { if (t != null) { exceptionCaught(ctx, t); return null; } HttpData content = msg.content(); ByteBuf returned = ctx.alloc().buffer(content.length() + 4); returned.writeInt(content.length()); if (content instanceof ByteBufHolder) { ByteBuf buf = ((ByteBufHolder) content).content(); try { returned.writeBytes(((ByteBufHolder) content).content()); } finally { buf.release(); } } else { returned.writeBytes(content.array(), content.offset(), content.length()); } if (responseIndex == previouslySentResponseIndex + 1) { ctx.writeAndFlush(returned); previouslySentResponseIndex++; flushResponses(ctx); } else { pendingResponses.put(responseIndex, returned); } return null; }); }