Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Request Scope when using child threads and cached executors

1,191 views
Skip to first unread message

Paul Lindner

unread,
Aug 3, 2009, 9:16:48 PM8/3/09
to google-guice
I've been looking into Reqest Scopes and GuiceFilter and noticed that
it uses a ThreadLocal to store the request state. This works fine for
single threaded request/response model. However if an application
uses a cached thread pool or child threads then injection is not
possible.

Is there a solution in the works for this situation? An
InheritableThreadLocal would suffice for threads created by the
request thread -- however using something like
Executors.newCachedThreadPool(); would not.

Thanks.
paul

Dhanji R. Prasanna

unread,
Aug 3, 2009, 9:22:53 PM8/3/09
to google...@googlegroups.com
On Tue, Aug 4, 2009 at 11:16 AM, Paul Lindner <lin...@inuus.com> wrote:

I've been looking into Reqest Scopes and GuiceFilter and noticed that
it uses a ThreadLocal to store the request state.  This works fine for
single threaded request/response model.  However if an application
uses a cached thread pool or child threads then injection is not
possible.

You mean asynchronous request processing? This isn't really within the HTTP request scope though =(
 

Is there a solution in the works for this situation?  An
InheritableThreadLocal would suffice for threads created by the
request thread -- however using something like
Executors.newCachedThreadPool(); would not.

The issue here is encapsulating your worker scope inside the relevant HTTP request. I would suggest a lookup boundary that identifies the request using some kind of processing token that can be passed to the worker pool. In fact we do exactly this in one of our major apps at Google.

I'm not particularly fond of keeping state around in thread locals, unfortunately this is a hack we have to live with given the servlet programming model...
Jesse also has some experience in this area, he might have different thoughts.
 
Dhanji.

Bob Lee

unread,
Aug 3, 2009, 10:31:37 PM8/3/09
to google...@googlegroups.com
I personally wouldn't inject HttpServletRequest anywhere deeper in the object graph than the servlet. 

Bob

Brian Pontarelli

unread,
Aug 4, 2009, 10:29:13 AM8/4/09
to google...@googlegroups.com

I provide HttpServletRequest injection throughout JCatapult because it is pretty much needed everywhere unless you use an adapter or just copy everything into another object. I also use the request pretty often in my action classes for retrieving additional bits of information on the request or just reading the input stream. In the end, any solution turns out to be almost identical to using the request itself. This is because the request or any type of wrapper/adapter/copy is scoped and should not be passed to singletons or objects whose life is longer than the requests life. I think you just need to be careful, but not injecting it at all seems too strict to me.

-bp

Tim Peierls

unread,
Aug 5, 2009, 3:41:42 PM8/5/09
to google-guice
There are several ways to pass ThreadLocal-ly held state across the
ExecutorService.execute boundary, all involving some kind of usage
restriction.

For example, the Restlet framework has several per-request values that
threads running in a thread pool might need access to. Restlet's
TaskService class lets you wrap a regular ExecutorService with a
decorator that passes these values through. I'm not saying this is
often (or even ever) a good thing to do; I'm just illustrating the
technique. Here's the code that accomplishes this, in the wrap()
method:

http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#XauSBc5aprQ/trunk/%20mmf-bsu-edu/forumaschat/lib/restlet-1.2m2/src/org.restlet/org/restlet/service/TaskService.java&q=lang:java%20RestletThreadFactory

--tim

Paul Lindner

unread,
Aug 6, 2009, 6:52:10 AM8/6/09
to google-guice
That's a nice technique. Thanks for sharing that.

For shindig's use of Guice this plus an InhertiableThreadLocal could
solve most Request Scoped issues, since we maintain our own Guice-
injected Executor that could be wrapped as you have done.

The only remaining issue I can see is thread-safeness. Many of the
things we might inject are mutable and may not be thread safe.

Thanks!
> http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#XauSBc5aprQ/...
>
> --tim
Reply all
Reply to author
Forward
0 new messages