FroMage / redpipe

Redpipe Web Framework
Apache License 2.0
70 stars 10 forks source link

Promises Not Working as Expected #47

Open saltwaterburning opened 6 years ago

saltwaterburning commented 6 years ago

Vert.x event thread blocked when using Promise for a blocking call as seen in the example below.

@GET @Path("blocker") public Single blocker(@QueryParam(value = "sleepSecs") long sleepSecs) { return Single.defer(() -> Single.just(blockingOperation(sleepSecs))); } private String blockingOperation(long secs) { try { Thread.sleep(TimeUnit.SECONDS.toMillis(secs)); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello world!"; }

If I add the Reasteasy rxjava/rxjava2 dependencies as I saw documented by JBoss I get a startup exception:

INFO: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10] java.lang.NullPointerException at net.redpipe.discovery.DiscoveryPlugin.lambda$init$0(DiscoveryPlugin.java:23) at io.reactivex.internal.operators.completable.CompletableDefer.subscribeActual(CompletableDefer.java:36) at io.reactivex.Completable.subscribe(Completable.java:2171) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableAssemblyAction$ContextPropagatorCompletable.subscribeActual(ContextPropagatorOnCompletableAssemblyAction.java:30) at io.reactivex.Completable.subscribe(Completable.java:2171) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.next(CompletableConcatArray.java:89) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onComplete(CompletableConcatArray.java:65) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.next(CompletableConcatArray.java:85) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onComplete(CompletableConcatArray.java:65) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.next(CompletableConcatArray.java:85) at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onComplete(CompletableConcatArray.java:65) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnCompletableCreateAction$ContextCapturerCompletable.onComplete(ContextPropagatorOnCompletableCreateAction.java:52) at io.reactivex.internal.operators.completable.CompletableFromSingle$CompletableFromSingleObserver.onSuccess(CompletableFromSingle.java:51) at io.reactiverse.reactivecontexts.propagators.rxjava2.ContextPropagatorOnSingleCreateAction$ContextCapturerSingle.onSuccess(ContextPropagatorOnSingleCreateAction.java:51) at io.vertx.reactivex.core.impl.AsyncResultSingle.lambda$subscribeActual$0(AsyncResultSingle.java:46) at io.vertx.reactivex.core.Vertx$5.handle(Vertx.java:644) at io.vertx.reactivex.core.Vertx$5.handle(Vertx.java:641) at io.vertx.core.impl.FutureImpl.setHandler(FutureImpl.java:79) at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:289) 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)

FroMage commented 6 years ago

In the first case, you can't actually use blocking code inside a fiber: fibers are lightweight threads scheduled on top of a real thread, so if you block the fiber you block the vert.x thread. You should use the vertx.rxExecuteBlocking() call to run your blocking code and then in the fiber you can await that.

In the second case you should not use the resteasy-rxjava and resteasy-rxjava2 modules until a newer version of resteasy and redpipe are both released with support for reactive-contexts. Until then, redpipe currently provides all the functionality of those two modules do you should not use them as they will conflict.