On Thu, May 12, 2016 at 5:21 AM Stuart Douglas <sdouglas(a)redhat.com> wrote:
This sounds like a bug, can you file a JIRA? I am traveling at the
moment but I will investigate when I get back.
Stuart
On Wed, May 11, 2016 at 10:54 AM, Oliver Dain <oliver(a)analyticspot.com>
wrote:
> I've got a case where I can call receiveFullBytes but neither the success
> nor the error handler is ever called. My code looks like this:
>
> public static CompletableFuture<ByteSource>
> getCompleteBody(HttpServerExchange exchange) {
> log.debug("In getCompleteBody.");
> CompletableFuture<ByteSource> finalResult = new
CompletableFuture<>();
> try {
> log.debug("Calling receiveFullBytes.");
> exchange.getRequestReceiver().receiveFullBytes(
> // Success case.
> (HttpServerExchange excng, byte[] bytes) -> {
> log.debug("getFullBytes completed with success.");
> finalResult.complete(ByteSource.wrap(bytes));
> },
>
> // Error case
> (HttpServerExchange exchng, IOException t) -> {
> log.warn("getFullBytes completed with an error:", t);
> finalResult.completeExceptionally(t);
> }
> );
> } catch (Throwable t) {
> log.warn("receiveFullBytes threw an exception:", t);
> finalResult.completeExceptionally(t);
> }
>
> return finalResult;
> }
>
> I've got a unit test that opens a socket, starts sending data, and then,
> intentionally throws an exception. The test then ensures that the
> CompletableFuture above completes with an exception. Except, it never
> completes.. the test just hangs forever. You can see that the
> "log.debug("Calling receiveFullBytes.")" line does get called
and that
the
> neither of the log lines in either callback is ever called. The full test
> looks like this:
>
> @Test
> public void getCompleteBodyCompletesWithExceptionOnBodyFailure() throws
> Exception {
> AtomicBoolean futureRedeemedWithError = new AtomicBoolean(false);
> CountDownLatch waitForInputToFail = new CountDownLatch(1);
>
> HttpHandler handler = new HttpHandler() {
> @Override
> public void handleRequest(HttpServerExchange exchange) throws
Exception
> {
> log.info("Handler called.");
> exchange.dispatch();
> log.info("Calling getCompleteBody");
> UndertowUtils.getCompleteBody(exchange).exceptionally((Throwable
t) ->
> {
> log.debug("As expected, received an exception:", t);
> futureRedeemedWithError.set(true);
> waitForInputToFail.countDown();
> return null;
> });
> }
> };
> UndertowTestUtils.RunningServer server =
> UndertowTestUtils.startUndertowOnFreePort(handler);
>
> // A Body() implementation that will return a few chunks of data but
the
> fail
> Body failingRequestBody = new Body() {
> private AtomicInteger readCalls = new AtomicInteger(0);
> @Override
> public long getContentLength() {
> return 1000;
> }
>
> @Override
> public long read(ByteBuffer buffer) throws IOException {
> if (readCalls.getAndIncrement() < 2) {
> byte[] toSend = "some data".getBytes(Charsets.UTF_8);
> buffer.put(toSend);
> return toSend.length;
> } else {
> throw new RuntimeException("Fake error on sending data.");
> }
> }
>
> @Override
> public void close() throws IOException {
> }
> };
>
> // A body generator using the above, busted Body.
> BodyGenerator failingBodyGenerator = new BodyGenerator() {
> @Override
> public Body createBody() throws IOException {
> return failingRequestBody;
> }
> };
>
> // This will start sending data so our handler gets invoked but it will
> then fail partway through.
> SimpleAsyncHttpClient client = new SimpleAsyncHttpClient.Builder()
> .setUrl(String.format("http://localhost:%s", server.getPort()))
> .build();
>
> client.post(failingBodyGenerator);
>
>
> // Test hangs here forever
> waitForInputToFail.await();
>
> assertThat(futureRedeemedWithError.get()).isTrue();
> }
>
>
> This feels like a bug. I'd expect the contract of "receiveFullBytes"
to
be
> that either the success or failure handler gets called exactly once. Is
this
> a bug? If not, what am I doing wrong?
>
> Thanks,
>
> Oliver
>
> --
> CTO, Analytic Spot
> 44 West Broadway #222
> Eugene, OR 97401
>
analyticspot.com • 425-296-6556
>
www.linkedin.com/in/oliverdain
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/undertow-dev