-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Version
5.0.2
Context
Hi,
Application is bootstrapped from MainVerticle in which start method three other verticles are deployed in order (because of dependency, imagine DB verticle, business logic verticle and web entry point verticle).
The plan was that the same three verticles are undeployed in revers order in MainVerticle stop method.
Application is started with io.vertx.launcher.application.VertxApplication MainVerticle
.
Now when JVM (application) is stopped verticles are being undeployed in random order even before MainVerticle.stop was invoked.
And eventually when MainVerticle.stop is invoked some verticles can not be undeployed, because they are already undeployed.
Is this expected behavior? In "Steps to reproduce" there is more details.
I would expect that (if overridden) MainVerticle stop method is called before it's child verticles are undeployed and eventual when stop is executed and there are some verticles as leftovers vertex to clean them up.
I could not find any more info in "Vert.x Core Manual" nor in "Vert.x in Action" book.
Thanks.
Regards,
N.
Steps to reproduce
In MainVerticle in start method I deployed three verticles like this:
public Future<?> start() {
return vertx
.deployVerticle(new FirstVerticle())
.compose(firstVerticleDeploymentId -> {
this.firstVerticleDeploymentId = firstVerticleDeploymentId ;
return vertx.deployVerticle(new SecondVerticle());
})
.compose(secondVerticleDeploymentId -> {
this.secondVerticleDeploymentId = secondVerticleDeploymentId ;
return vertx.deployVerticle(new ThirdVerticle());
})
.compose(thirdVerticleDeploymentId -> {
this.thirdVerticleDeploymentId = thirdVerticleDeploymentId ;
return Future.succeededFuture();
})
.onSuccess(e -> logger.info("All verticles are deployed."))
.onFailure(t -> logger.error("There is an error while deploying verticles.", t));
}
Now in stop method I wanted to undeploy them in reverse order like this:
public Future<?> stop() throws Exception {
Future<Void> thirdVerticleUndeploy = thirdVerticleDeploymentId == null ? Future.succeededFuture() : vertx.undeploy(thirdVerticleDeploymentId);
return thirdVerticleUndeploy
.compose(unused -> {
return secondVerticleDeploymentId == null ? Future.succeededFuture() : vertx.undeploy(secondVerticleDeploymentId);
})
.compose(unused -> {
return firstVerticleDeploymentId == null ? Future.succeededFuture() : vertx.undeploy(firstVerticleDeploymentId);
})
.onSuccess(e -> logger.info("All verticles are undeployed."))
.onFailure(t -> logger.error("There is an error while undeploying verticles.", t));
}
When I start application with io.vertx.launcher.application.VertxApplication MainVerticle deployment happen as expected in order.
Now when I stop JVM (stop application) verticles are beeing undeploy in random order even before MainVerticle.stop was invoked.
And eventually when MainVerticle.stop is invoked some verticles can not be undeployed, because they are already undeployed , throwing:
java.lang.IllegalStateException: Unknown deployment
at io.vertx.core.impl.deployment.DefaultDeploymentManager.undeploy(DefaultDeploymentManager.java:56)
at io.vertx.core.impl.VertxImpl.lambda$undeploy$24(VertxImpl.java:855)
at io.vertx.core.impl.future.Composition.complete(Composition.java:40)
at io.vertx.core.impl.future.FutureBase.emitResult(FutureBase.java:68)
at io.vertx.core.impl.future.SucceededFuture.addListener(SucceededFuture.java:89)
at io.vertx.core.impl.future.FutureBase.compose(FutureBase.java:84)
at io.vertx.core.Future.compose(Future.java:391)
at io.vertx.core.impl.VertxImpl.undeploy(VertxImpl.java:855)
at MainVerticle.stop(MainVerticle.java:47)
at io.vertx.core.VerticleBase.undeploy(VerticleBase.java:79)
at io.vertx.core.impl.deployment.DefaultDeployment.lambda$undeploy$6(DefaultDeployment.java:223)
at io.vertx.core.internal.ContextInternal.dispatch(ContextInternal.java:249)
at io.vertx.core.internal.ContextInternal.dispatch(ContextInternal.java:231)
at io.vertx.core.internal.ContextInternal.lambda$runOnContext$0(ContextInternal.java:50)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:148)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:141)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:507)
at io.netty.channel.SingleThreadIoEventLoop.run(SingleThreadIoEventLoop.java:183)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1073)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Do you have a reproducer?
No response