[Java Play 2.5/2.6] - Accessing HttpContext inside a custom execution context

411 views
Skip to first unread message

Patrick Li

unread,
Dec 14, 2017, 12:16:37 AM12/14/17
to Play Framework
Hi,

I have created a custom execution context to run all my blocking DB calls, as explained in the ThreadPools documentation. Essentially, I wrap all my DB code in something like below:

return CompletableFuture.supplyAsync(new Supplier<List<Customer>>() {
   
@Override
    public List<Customer> get() {
       
return jpaApi.withTransaction(new Function<EntityManager, List<Customer>>() {
           
@Override
            public List<Customer> apply(EntityManager entityManager) {
               
return customerDao.findAll(entityManager);
           
}
       
});
   
}
}, databaseExecutionContext);

Now I need to get access to the HttpContext, for things like session, etc... in the customerDao.findAll code. Since that part is running in the custom database execution context, I get the There is no HTTP Context error. Then I saw the below text on the same ThreadPools documentation page:

If you have a custom executor, you can wrap it in an HttpExecutionContext simply by passing it to the HttpExecutionContext's constructor.

Does this mean there is some way to make HttpContext available in my custom execution context? If so, can someone please provide some code snippet?

Thanks
Patrick

Greg Methvin

unread,
Dec 14, 2017, 6:08:08 AM12/14/17
to play-framework
play.libs.concurrent.HttpExecutionContext is just a wrapper for an Executor with a .current() method. It can wrap any executor, for example:

HttpExecutionContext dbHttpExecutor = new HttpExecutionContext(dbExecutor);

Note that injecting a HttpExecutionContext by default uses Play's default executor. If you want to be able to inject your custom HttpExecutionContext you should use a subclass or binding annotation.

Then it can be used like:

CompletableFuture.supplyAsync({ /* some code */ }, dbHttpExecutor.current());

When I call dbHttpExecutor.current(), The HttpExecutionContext helper reads the Http.Context.current() from the current thread and creates an Executor that, for every Runnable executed, it sets the Http.Context at the start of execution and unsets it at the end. Otherwise it behaves just like the wrapped Executor.

All that said, usually you want to separate your database repositories from code that accesses/modifies request information. If you need to access session info, it's probably better to get that info and pass it to a method that makes the database queries.


--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/340d93a8-17be-450d-9e7e-9ee253ad5b7d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

Patrick Li

unread,
Dec 14, 2017, 4:41:05 PM12/14/17
to Play Framework
Thanks Greg. Yeah, I agree, passing the actual values to the methods that need them is a clearner/safer approach. Unfortunately, I am using Hibernate's AttributeConverter, which does not take params as far as I can tell, so the only way I can think of to pass values to it is via Http context.

So looking at the HttpExecutionContext class, I see the following line, which I think sets the Http.Context, where and how do it unset it as you mentioned?

public Executor current() {
   
return HttpExecution.fromThread(delegate);
}

Thanks
Patrick
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Greg Methvin

unread,
Dec 14, 2017, 4:56:33 PM12/14/17
to play-framework
You don't need to unset anything. HttpExecution.fromThread creates a wrapped executor. When you execute a runnable in that executor, it takes care of setting/unsetting around that code. The actual code is here: https://github.com/playframework/playframework/blob/2.6.x/framework/src/play/src/main/scala/play/core/j/HttpExecutionContext.scala#L54

To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/6d6d223d-b53d-4980-bbbd-89a1a101a3ea%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages