vertx-sync icon indicating copy to clipboard operation
vertx-sync copied to clipboard

Unit tests to reproduce NPE in the awaitResult() method from Sync class.

Open fperie opened this issue 5 years ago • 30 comments

Hello @vietj, @jponge,

this new pull request reproduces two issues with vertx 3.6.0-SNAPSHOT :

  1. with vertx-codegen and vertx-service-proxy 3.6.0-SNAPSHOT, no class is generated I use a workaround: I force the using vertx-codegen and vertx-service-proxy 3.5.4

  2. During the unit test, a NPE occured on the awaitResult() method, at line 50, from Sync class. I'am with the vertx-sync last snapshot with quasar-core 0.7.10 and quasar-maven-plugin 0.7.9 Why this error ?

Below, the stack trace :

Caused by: io.vertx.core.VertxException: io.vertx.core.VertxException: java.lang.NullPointerException
        at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$onStarting$986b261$1(DaoSyncVerticle.java:56)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
        at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.RunnableFiberTask.unpark(RunnableFiberTask.java:274)
        at co.paralleluniverse.fibers.Fiber.unpark(Fiber.java:1352)
        at co.paralleluniverse.fibers.FiberAsync.fire(FiberAsync.java:366)
        at co.paralleluniverse.fibers.FiberAsync.asyncFailed(FiberAsync.java:344)
        at io.vertx.ext.sync.impl.AsyncAdaptor.handle(AsyncAdaptor.java:18)
        at io.vertx.ext.sync.impl.AsyncAdaptor.handle(AsyncAdaptor.java:11)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.createMongoCollectionsAndCreateIndexesIfNeeded(DaoSyncVerticle.java:133)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$null$0(DaoSyncVerticle.java:56)
        at io.vertx.ext.sync.Sync$1.requestAsync(Sync.java:43)
        at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:128)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:824)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.onStarting(DaoSyncVerticle.java:59)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.lambda$start$bd183658$1(AbstractSyncVerticle.java:37)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
        at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.start(AbstractSyncVerticle.java:43)
        at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:494)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)
Caused by: io.vertx.core.VertxException: java.lang.NullPointerException
        at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.createMongoCollectionsAndCreateIndexesIfNeeded(DaoSyncVerticle.java:120)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$null$0(DaoSyncVerticle.java:56)
        at io.vertx.ext.sync.Sync$1.requestAsync(Sync.java:43)
        at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:128)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:824)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.onStarting(DaoSyncVerticle.java:59)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.lambda$start$bd183658$1(AbstractSyncVerticle.java:37)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
        at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.start(AbstractSyncVerticle.java:43)
        at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:494)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

Thanks for your help, Fabien

fperie avatar Nov 17 '18 01:11 fperie

can you make a separate PR with the issue for codegen on the service-proxy repo ?

vietj avatar Nov 17 '18 08:11 vietj

Yes @vietj, but I'm not sure to have the time to do it today.

fperie avatar Nov 17 '18 09:11 fperie

For the issue on the service proxy, I have a workaround while on npe issue, it's blocking

fperie avatar Nov 17 '18 09:11 fperie

can you investigate that @jponge ?

vietj avatar Nov 17 '18 09:11 vietj

@vietj As requested, I created a new pull request PR #83 in service-proxy module in service-proxy project but I don't reproduce this issue. Why ?

fperie avatar Nov 17 '18 22:11 fperie

I can’t have a look to this right now, but I’ll try later this week.

On 17 Nov 2018, at 23:42, Fabien PÉRIÉ [email protected] wrote:

@vietj As requested, I created a new pull request PR #83 in service-proxy module in service-proxy project but I don't reproduce this issue. Why ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

jponge avatar Nov 19 '18 08:11 jponge

Hola @vietj,

This issue can it be resolved to vertx 3.6.0 ?

fperie avatar Nov 22 '18 20:11 fperie

The awaitResult in testFindAll is not being called from a fiber. That may explain the error that you get.

jponge avatar Nov 22 '18 21:11 jponge

Hello @vietj, @jponge,

Oups, excellent suggestions but the new patchset don't resolve the issue. Always, an NPE occured during the execution of test :

Caused by: java.lang.NullPointerException: null
        at co.paralleluniverse.fibers.FiberAsync.run(FiberAsync.java:122)
        at io.vertx.ext.sync.Sync.awaitResult(Sync.java:48)

fperie avatar Nov 22 '18 22:11 fperie

I’m travelling so it’s not ideal to investigate.

The stack traces aren’t really helpful, can please you insert console traces to point to the piece of your code that eventually leads to a crash?

jponge avatar Nov 22 '18 22:11 jponge

Hello @vietj, @jponge,

Below, the full stack trace :

Caused by: java.lang.NullPointerException: null
        at co.paralleluniverse.fibers.FiberAsync.run(FiberAsync.java:122)
        at io.vertx.ext.sync.Sync.awaitResult(Sync.java:48)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.createMongoCollectionsAndCreateIndexesIfNeeded(DaoSyncVerticle.java:120)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$null$0(DaoSyncVerticle.java:56)
        at io.vertx.ext.sync.Sync$1.requestAsync(Sync.java:43)
        at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:128)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:824)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.onStarting(DaoSyncVerticle.java:59)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.lambda$start$bd183658$1(AbstractSyncVerticle.java:37)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
        at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
        at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
        at io.vertx.ext.sync.Sync.lambda$getContextScheduler$2(Sync.java:202)
        at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
        at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
        at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
        at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.start(AbstractSyncVerticle.java:43)
        at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:494)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

Below, the code which throws the null pointer exception :

protected void createMongoCollectionsAndCreateIndexesIfNeeded(final Handler<AsyncResult<Void>> result) 
{
	Void res;
	try
	{
		final List<String> collections = Sync.awaitResult(h -> mongoClient.getCollections(h)); // ==> throw NPE
		...
		...
	}
}

The createMongoCollectionsAndCreateIndexesIfNeeded() method is called from the onStarting() method which wrapped this call in a fiber:

@Suspendable
@Override
protected void onStarting(final Future<Void> onStartingFuture) 
{
	try
	{
		LOGGER.info("Initializing DaoSyncVerticle ...");
		
		serviceBinder = new ServiceBinder(vertx);
		
		final JsonObject config = createMongoConfiguration();
		registerUserDao(config);
		
		mongoClient = MongoClient.createNonShared(vertx, config);
		new Fiber<Void>(() -> {
			Void res = Sync.awaitResult(h -> createMongoCollectionsAndCreateIndexesIfNeeded(h));
			res = Sync.awaitResult(h -> initUserDataIfNeeded(h));
			res = Sync.awaitResult(h -> afterMongoStarting(h));
		}).start().get();
		
		LOGGER.info("DaoSyncVerticle starts with success.   [ OK ]");
		onStartingFuture.complete();
	}
	catch (MongoException | VertxException | ExecutionException | InterruptedException me)
	{
		LOGGER.info("Fail to start DaoSyncVerticle: ", me);
		onStartingFuture.fail(me);
	}
}

fperie avatar Nov 22 '18 22:11 fperie

Hello @vietj, @jponge,

When will vertx 3.6.0 final be released ? Is there a forecast date ?

Are you going to have time to work on this issue ?

Thank's a lot, Fabien

fperie avatar Nov 27 '18 20:11 fperie

@fperie we expect to tag this week, likely tomorrow

vietj avatar Nov 27 '18 20:11 vietj

Hi Fabien,

This issue will be delayed to 3.6.1. At this stage it is not clear to me if this is a proper bug or an issue with your code.

Thanks

On 27 Nov 2018, at 21:03, Fabien PÉRIÉ [email protected] wrote:

Hello @vietj, @jponge,

When will vertx 3.6.0 final be released ? Is there a forecast date ?

Are you going to have time to work on this issue ?

Thank's a lot, Fabien

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

jponge avatar Nov 27 '18 20:11 jponge

Hi @jponge, @vietj, Too bad, it's a shame because vertx-sync would have allowed me to fight the hell of callbacks. This issue is blocking and I will do otherwise with CompletableFuture. Thank's a lot, Fabien

fperie avatar Nov 27 '18 21:11 fperie

If that helps: 3.6.1 should be here in 2018.

If you are interested in CompletableFuture, you might as well look at the RxJava integration.

Be careful with CompletableFuture, as you will likely execute code outside of event-loop threads...

On 27 Nov 2018, at 22:38, Fabien PÉRIÉ [email protected] wrote:

Hi @jponge, @vietj, Too bad, it's a shame because vertx-sync would have allowed me to fight the hell of callbacks. This issue is blocking and I will do otherwise with CompletableFuture. Thank's a lot, Fabien

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

jponge avatar Nov 27 '18 21:11 jponge

@jponge @vietj I can wait a little longer

fperie avatar Nov 27 '18 22:11 fperie

Hello @jponge, @vietj

Have you got a release date to vertx 3.6.1 and vertx 4.0.0 ?

Thank's Fabien

fperie avatar Dec 02 '18 21:12 fperie

@fperie I hope we can pull a 3.6.1 on week of 17/12/18 4.0.0 no date but we'll make milestones when there is noticeable progress

vietj avatar Dec 03 '18 08:12 vietj

hello @jponge, @vietj Can you watch this bug for vertx 3.6.1 ?

Thank's a lot, Fabien

fperie avatar Dec 05 '18 17:12 fperie

@jponge can you handle this for 3.6.1 ?

vietj avatar Dec 05 '18 17:12 vietj

It’s on my radar

On 5 Dec 2018, at 18:04, Julien Viet [email protected] wrote:

@jponge can you handle this for 3.6.1 ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

jponge avatar Dec 05 '18 17:12 jponge

I locally changed your DaoSyncVerticle to use start and stop methods rather than onStarting and onStopping (see the docs).

Then running the tests I get a big stack trace showing that somehow, you have calls not being made from a fiber:


java.util.concurrent.ExecutionException: io.vertx.core.VertxException: io.vertx.core.VertxException: java.lang.IllegalThreadStateException: Method called not from within a fiber

	at co.paralleluniverse.fibers.Fiber.get(Fiber.java:1388)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.start(DaoSyncVerticle.java:59)
	at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:491)
	at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:339)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)
Caused by: io.vertx.core.VertxException: io.vertx.core.VertxException: java.lang.IllegalThreadStateException: Method called not from within a fiber
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$start$986b261$1(DaoSyncVerticle.java:56)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
	at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
	at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
	at co.paralleluniverse.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:271)
	at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:117)
	at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:74)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1021)
	at java.util.concurrent.ForkJoinPool$WorkQueue.execLocalTasks(ForkJoinPool.java:1046)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1058)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: io.vertx.core.VertxException: java.lang.IllegalThreadStateException: Method called not from within a fiber
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.createMongoCollectionsAndCreateIndexesIfNeeded(DaoSyncVerticle.java:120)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$null$0(DaoSyncVerticle.java:56)
	at io.vertx.ext.sync.Sync$1.requestAsync(Sync.java:43)
	at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:128)
	at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:824)
	at co.paralleluniverse.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:271)
	at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:117)
	at co.paralleluniverse.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:74)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	... 2 more
Caused by: java.lang.IllegalThreadStateException: Method called not from within a fiber
	at co.paralleluniverse.fibers.FiberAsync.requestSync(FiberAsync.java:300)
	at co.paralleluniverse.fibers.FiberAsync.runSync(FiberAsync.java:259)
	at co.paralleluniverse.fibers.FiberAsync.run(FiberAsync.java:112)
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:48)
	... 12 more

I then changed your initialization code to:

     instanceScheduler.newFiber(() -> {
        Void res = Sync.awaitResult(h -> createMongoCollectionsAndCreateIndexesIfNeeded(h));
        res = Sync.awaitResult(h -> initUserDataIfNeeded(h));
        res = Sync.awaitResult(h -> afterMongoStarting(h));
        return null;
      }).start();

so you get a fiber from the proper scheduler. And then I have issues connecting to MongoDB, but I don't have it running locally on port 53807 as in your tests.

jponge avatar Dec 07 '18 10:12 jponge

@fperie you may want to check on your side with the tiny changes that I did if you can make progress.

jponge avatar Dec 07 '18 10:12 jponge

Hello @jponge,

in my mind, the onStarting() and onStoping() methods should signal to the caller the end of the startup process or the termination of the verticle. I would like to start a sync DAO verticle which initialize a database with some data and after initializing, to launch unit tests. That's possible ?

Other question: in your example, when you instanciate the fiber, attached to instanceScheduler of sync verticle, you call the start() method, which is blocking, no ?

Thank's for your help (I feel like a shit ), Fabien

fperie avatar Dec 07 '18 21:12 fperie

Hello @jponge,

trying to follow your logic, I get the stack trace below because the verticle has not finished to start when the test is starting

Exception in Fiber "fiber-10000002" io.vertx.core.VertxException: (NO_HANDLERS,-1) No handlers for address dao.user
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.UserDaoTest.lambda$0(UserDaoTest.java:128)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)

fperie avatar Dec 07 '18 21:12 fperie

Hello @jponge,

I try to keep the onStarting method with the below code to prevent the caller that the operation is finished :

@Suspendable
@Override
protected void onStarting(final Future<Void> onStartingFuture) 
{
	try
	{
		LOGGER.info("Initializing DaoSyncVerticle ...");
		
		serviceBinder = new ServiceBinder(vertx);
		
		final JsonObject config = createMongoConfiguration();
		registerUserDao(config);
		
		mongoClient = MongoClient.createNonShared(vertx, config);

		new Fiber<Void>(instanceScheduler, () -> {
			LOGGER.info("before createMongoCollectionsAndCreateIndexesIfNeeded() method in DaoSyncVerticle");
			Void res = Sync.awaitResult(h -> createMongoCollectionsAndCreateIndexesIfNeeded(h));
			LOGGER.info("after createMongoCollectionsAndCreateIndexesIfNeeded() method in DaoSyncVerticle");
			
			res = Sync.awaitResult(h -> initUserDataIfNeeded(h));
			LOGGER.info("after initUserDataIfNeeded() method in DaoSyncVerticle");
			
			res = Sync.awaitResult(h -> afterMongoStarting(h));
			LOGGER.info("after afterMongoStarting() method in DaoSyncVerticle");
			
			LOGGER.info("DaoSyncVerticle starts with success.   [ OK ]");
			onStartingFuture.complete();
		}).start();
	}
	catch (MongoException | VertxException me)
	{
		LOGGER.info("Fail to start DaoSyncVerticle: ", me);
		onStartingFuture.fail(me);
	}
}

The idea is that the following instruction : « onStartingFuture.complete(); » is called in the end of the fiber and the fiber is attached to instanceScheduler of SyncVerticle.

One exception occured during the execution:

QUASAR WARNING: Assertions enabled. This may harm performance.
Initializing DaoSyncVerticle ... 
Opened connection [connectionId{localValue:1}] to 127.0.0.1:59256 
Monitor thread successfully connected to server with description ServerDescription{address=127.0.0.1:59256, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 0, 0]}, minWireVersion=2, maxWireVersion=2, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=null, roundTripTimeNanos=3962600} 
Cluster created with settings {hosts=[127.0.0.1:59256], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500} 
user dao service   [ OK ] 
Cluster created with settings {hosts=[127.0.0.1:59256], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500} 
before createMongoCollectionsAndCreateIndexesIfNeeded() method in DaoSyncVerticle 
Exception in Fiber "fiber-vertx.contextScheduler-10000002" io.vertx.core.VertxException: io.vertx.core.VertxException: co.paralleluniverse.fibers.SuspendExecution: Oops. Forgot to instrument a method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation=true to catch the culprit!
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$0(DaoSyncVerticle.java:59)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
Exception in Fiber "fiber-vertx.contextScheduler-10000002" io.vertx.core.VertxException: io.vertx.core.VertxException: co.paralleluniverse.fibers.SuspendExecution: Oops. Forgot to instrument a method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation=true to catch the culprit!
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$0(DaoSyncVerticle.java:59)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
Fail to start DaoSyncVerticle:  
io.vertx.core.VertxException: io.vertx.core.VertxException: co.paralleluniverse.fibers.SuspendExecution: Oops. Forgot to instrument a method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation=true to catch the culprit!
	at io.vertx.ext.sync.Sync.awaitResult(Sync.java:50)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.lambda$0(DaoSyncVerticle.java:59)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
	at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
	at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
	at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
	at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
	at io.vertx.ext.sync.Sync.lambda$2(Sync.java:202)
	at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
	at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
	at co.paralleluniverse.fibers.RunnableFiberTask.unpark(RunnableFiberTask.java:274)
	at co.paralleluniverse.fibers.Fiber.unpark(Fiber.java:1352)
	at co.paralleluniverse.fibers.FiberAsync.fire(FiberAsync.java:366)
	at co.paralleluniverse.fibers.FiberAsync.asyncFailed(FiberAsync.java:344)
	at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:131)
	at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:824)
	at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
	at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
	at io.vertx.ext.sync.Sync.lambda$2(Sync.java:202)
	at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
	at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
	at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
	at io.vertx.ext.sync.npe.verticle.DaoSyncVerticle.onStarting(DaoSyncVerticle.java:70)
	at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.lambda$0(AbstractSyncVerticle.java:37)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:44)
	at co.paralleluniverse.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:32)
	at co.paralleluniverse.fibers.Fiber.run(Fiber.java:1097)
	at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
	at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
	at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
	at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
	at io.vertx.ext.sync.Sync.lambda$2(Sync.java:202)
	at co.paralleluniverse.fibers.FiberExecutorScheduler.execute(FiberExecutorScheduler.java:85)
	at co.paralleluniverse.fibers.RunnableFiberTask.submit(RunnableFiberTask.java:296)
	at co.paralleluniverse.fibers.Fiber.start(Fiber.java:1129)
	at io.vertx.ext.sync.npe.verticle.AbstractSyncVerticle.start(AbstractSyncVerticle.java:43)
	at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:494)
	at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
	at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:462)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)
Caused by: io.vertx.core.VertxException: co.paralleluniverse.fibers.SuspendExecution: Oops. Forgot to instrument a method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation=true to catch the culprit!
	at io.vertx.ext.sync.Sync$1.requestAsync(Sync.java:45)
	at co.paralleluniverse.fibers.FiberAsync$1.run(FiberAsync.java:128)
	... 30 more
Caused by: co.paralleluniverse.fibers.SuspendExecution: Oops. Forgot to instrument a method. Run your program with -Dco.paralleluniverse.fibers.verifyInstrumentation=true to catch the culprit!

All methods are annoted with @Suspendable except the client methods to the mongoDB database. That's a problem ?

Thank's a lot, Fabien

fperie avatar Dec 07 '18 22:12 fperie

Please first try again with using the scheduler, not directly starting a fiber.

Then @Suspendable marks methods that Quasar shall try to make suspendable for fibers, but it may fail to do so for many reasons, like calling methods that block (think synchronized, Thread.sleep, etc)

jponge avatar Dec 10 '18 08:12 jponge

Hello @jponge,

If you watch the AbstractSyncVerticle java class, the start() method get the context from scheduler :

@Override
public void start(final Future<Void> startFuture) throws Exception 
{
	final Future<Void> onStartingFuture = Future.future();
	onStartingFuture.setHandler(new Handler<AsyncResult<Void>>() 
	{
		@Override
		public void handle(final AsyncResult<Void> onStartingFutureEvent) 
		{
			if (onStartingFutureEvent.succeeded())
			{
				startFuture.complete();
			}
			else
			{
				startFuture.fail(onStartingFutureEvent.cause());
			}
		}
	});		
	
	instanceScheduler = Sync.getContextScheduler();
	new Fiber<Void>(instanceScheduler, () -> {
		try 
		{
			onStarting(onStartingFuture);
		} 
		catch (final Throwable t) 
		{
			startFuture.fail(t);
		}
	}).start();
}

I don't understand why this code doesn't work !

I tried an another workaround that works. I declare in my proxy service a new init() method: void init(Handler<AsyncResult<Void> result); which populates the database and which is called after the initialization of the verticle. And it works well !!

Thank's a lot for your help, Fabien

fperie avatar Dec 10 '18 21:12 fperie

I declare in my proxy service a new init() method: void init(Handler<AsyncResult<Void> result); which populates the database and which is called after the initialization of the verticle.

Ah good then

jponge avatar Dec 11 '18 08:12 jponge