Skip to content

Instantly share code, notes, and snippets.

@chefhoobajoob
Last active July 31, 2017 15:39
Show Gist options
  • Save chefhoobajoob/066fc3c8c5bb5c1c8335135c8d73a43f to your computer and use it in GitHub Desktop.
Save chefhoobajoob/066fc3c8c5bb5c1c8335135c8d73a43f to your computer and use it in GitHub Desktop.
Reproducer for vertx-health-check-js error when completing futures with status
module.exports = {
vertxStartAsync: function (startFuture) {
vertx.executeBlocking(function (blockingFuture) {
try {
var Router = require("vertx-web-js/router");
var router = Router.router(vertx);
var handler = require("vertx-health-checks-js/health_check_handler").create(vertx);
handler.register("complete-with-ok", function (future) {
console.log('>>> verticle: complete-with-ok: ' +
'completing future with: {ok: true}');
future.complete( {ok: true} );
console.log('>>> complete-with-ok: done')
});
handler.register("complete-with-nothing", function (future) {
console.log('>>> verticle: complete-with-nothing: completing future');
future.complete();
console.log('>>> verticle: complete-with-nothing: done')
});
router.get("/health/*").handler(handler.handle);
var server = vertx.createHttpServer();
server.requestHandler(router.accept).listen(5050);
console.log('>>> verticle: now listening on port 5050')
blockingFuture.complete()
} catch(error) {
blockingFuture.fail(error)
}
}, function(result, error) {
error ? startFuture.fail(error) : startFuture.complete();
})
},
vertxStop: function () {
logger.debug('verticle stopped')
}
};
package org.github.hoobajoob.vertx.health.tests;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.rxjava.core.Vertx;
import io.vertx.rxjava.ext.web.client.WebClient;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(VertxUnitRunner.class)
public class JavascriptHealthChecks {
@Test(timeout=10000L)
public void test( TestContext context ) {
Vertx vertx = Vertx.vertx();
Async deploy = context.async();
System.out.println(">>> test: starting health check verticle");
vertx.deployVerticle( "HealthCheck.js", context.asyncAssertSuccess(id -> deploy.complete()) );
deploy.await();
WebClient client = WebClient.create(vertx);
System.out.println(">>> test: sending complete-with-nothing health check");
Async nothing = context.async();
client.get(5050, "localhost", "/health/complete-with-nothing")
.send( async -> {
if ( async.failed() ) {
System.out.println(">>> test: there's a problem, occifer: " + async.cause().getMessage() );
async.cause().printStackTrace();
nothing.complete();
}
System.out.println(">>> test: got a (" + async.result().statusCode() +
") response:\n" + async.result().bodyAsJsonObject().encode() );
nothing.complete();
});
nothing.await();
System.out.println(">>> test: sending complete-with-ok health check");
Async ok = context.async();
client.get(5050, "localhost", "/health/complete-with-ok")
.send( async -> {
if ( async.failed() ) {
System.out.println(">>> test: there's a problem, occifer: " + async.cause().getMessage() );
async.cause().printStackTrace();
ok.complete();
}
System.out.println(">>> test: got a (" + async.result().statusCode() +
") response:\n" + async.result().bodyAsJsonObject().encode() );
ok.complete();
});
}
}
@chefhoobajoob
Copy link
Author

chefhoobajoob commented Jun 9, 2017

NOTE: this depends on codegen output in order to provide vertx-health Status results to the health check handler's future on completion. There is currently no other means we could find to provide status to future.complete()

UPDATE: same behavior occurs without the codegen StatusFactory, so removed those files and updated the verticle code accordingly.

@chefhoobajoob
Copy link
Author

When the junit test runs, it times out waiting for the complete-with-ok procedure, which throws during execution and does not provide a response.

@chefhoobajoob
Copy link
Author

chefhoobajoob commented Jun 9, 2017

Here is a dump of the stdout from running this test:

>>> test: starting health check verticle
>>> verticle: now listening on port 5050
>>> test: sending complete-with-nothing health check
>>> verticle: complete-with-nothing: completing future
>>> verticle: complete-with-nothing: done
>>> test: got a (200) response:
{"id":"complete-with-nothing","status":"UP","outcome":"UP"}
>>> test: sending complete-with-ok health check
>>> verticle: complete-with-ok: completing future with: {ok: true}

Jun 08, 2017 5:18:03 PM io.vertx.ext.web.impl.RoutingContextImplBase
SEVERE: Unexpected exception in route
java.lang.IllegalStateException: Result is already complete: succeeded
	at io.vertx.core.impl.FutureImpl.fail(FutureImpl.java:121)
	at io.vertx.ext.healthchecks.impl.DefaultProcedure.check(DefaultProcedure.java:55)
	at io.vertx.ext.healthchecks.impl.HealthChecksImpl.compute(HealthChecksImpl.java:135)
	at io.vertx.ext.healthchecks.impl.HealthChecksImpl.invoke(HealthChecksImpl.java:114)
	at io.vertx.ext.healthchecks.impl.HealthCheckHandlerImpl.handle(HealthCheckHandlerImpl.java:71)
	at jdk.nashorn.internal.scripts.Script$Recompilation$200$2113A$\^eval\_#88\!17\^eval\_.L:1$HealthCheckHandler$handle(.vertx\debug-js\vertx-health-checks-js\health_check_handler.js:57)
	at jdk.nashorn.internal.scripts.Script$Recompilation$182$5522A$\^eval\_#88\!17\^eval\_.L:1$Route$handler$L:156(.vertx\debug-js\vertx-web-js\route.js:157)
	at io.vertx.core.Handler$$NashornJavaAdapter.handle(Unknown Source)
	at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:217)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:118)
	at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79)
	at jdk.nashorn.internal.scripts.Script$Recompilation$197$1500A$\^eval\_#88\!17\^eval\_.L:1$Router$accept(.vertx\debug-js\vertx-web-js\router.js:48)
	at jdk.nashorn.internal.scripts.Script$Recompilation$187$2902A$\^eval\_#88\!17\^eval\_.L:1$HttpServer$requestHandler$L:83(.vertx\debug-js\vertx-js\http_server.js:84)
	at io.vertx.core.Handler$$NashornJavaAdapter.handle(Unknown Source)
	at io.vertx.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:285)
	at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:429)
	at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:131)
	at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.lambda$createConnAndHandle$1(HttpServerImpl.java:763)
	at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:335)
	at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:193)
	at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.createConnAndHandle(HttpServerImpl.java:757)
	at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:621)
	at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:573)
	at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:76)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:122)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	at io.vertx.core.http.impl.HttpServerImpl$Http1xOrHttp2Handler.http1(HttpServerImpl.java:1064)
	at io.vertx.core.http.impl.HttpServerImpl$Http1xOrHttp2Handler.channelRead(HttpServerImpl.java:1035)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at java.lang.Thread.run(Thread.java:745)


java.util.concurrent.TimeoutException
	at io.vertx.ext.unit.impl.TestContextImpl$Step.lambda$run$0(TestContextImpl.java:112)
	at java.lang.Thread.run(Thread.java:745)


Process finished with exit code -1

@cescoffier
Copy link

Having a look right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment