I'm using Play 2.5 to build a simple app. For better performance I'm using Akka chunked response with Java 8 CompletionStage strategy. Below is the code by which chunked response is getting generated(it's working fine when not using ComperableFuture):
@Singleton
public class AbstractSource {
public Source<ByteString, ?> getChunked(String html) {
return Source.<ByteString>actorRef(256, OverflowStrategy.dropNew())
.mapMaterializedValue(sourceActor -> {
sourceActor.tell(ByteString.fromString(html), null);
sourceActor.tell(new Status.Success(NotUsed.getInstance()), null);
return null;
});
}
}
And here is my controller:
@Singleton
@AddCSRFToken
public class Application extends Controller {
@Inject
private AbstractSource abstractSource;
public CompletionStage<Result> index() {
CompletionStage<Source<ByteString, ?>> source = CompletableFuture.supplyAsync(() ->
abstractSource.getChunked(index.render(CSRF.getToken(request()).map(t ->
t.value()).orElse("no token")).body()
)
);
return source.thenApply( chunks -> ok().chunked(chunks));
}
}
Now when I'm running the app it's throwing following exception:
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.RuntimeException: There is no HTTP Context available from here.]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:269)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:195)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:98)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.lang.RuntimeException: There is no HTTP Context available from here.
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:57)
at play.mvc.Controller.request(Controller.java:36)
at com.mabsisa.ui.web.controllers.Application.lambda$index$1(Application.java:31)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
... 5 common frames omitted
I'm not using HTTP context anywhere, so why this is not working I'm not getting. Same code is working when returning normal Result with chunked response. Please help with this
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…