3

I'm currently working on a product that we've set up to use guice-servlet.

For each request that we receive, we spawn a bunch of worker threads, each of which go off and perform a "task". The results of those tasks are then merged to produce a response.

This is pretty common/straightforward, but something I haven't attempted to marry with Guice before. Unfortunately we've got ourselves into a situation where you have to draw the whole graph in advance.

i.e. We can't do any deferred binding within a child thread, as that will try to use request/session-scoped stuff that isn't there.


A couple of questions that are interrelated:

1) It'd be really nice to be able to have access to request-scoped objects from within our task threads. I was initially tempted by (and played around with) ServletScopes.transferRequest(), but was deflated by the following:

Because request-scoped objects are not typically thread-safe, the callable returned by this method must not be run on a different thread until the current request scope has terminated. The returned callable will block until the current thread has released the request scope.

It seems like this is more for post-processing in a separate thread (i.e. do some work after you've responded) and the concerns about thread-safety are valid.

Is the Guicy™ way of dealing with this to create a child-injector with a separate module for task-only stuff and seed it with things from the request-scope that are required/immutable?

Reading this back, it seems a little clumsy/heavy-handed, so I'm probably wrong.

2) As you can imagine, creating a custom task-scope for our worker threads would be nice.

I had something working when I was incorrectly mucking around with ServletScopes.transferRequest()) BUT the CustomScopes page advises against creating custom scopes:

It is generally recommended that users do not write their own custom scopes — the built-in scopes should be sufficient for most applications.

Is there a better approach for scoping things within our task-threads?

Thanks in advance!!

phippsnatch
  • 186
  • 7
  • You've not provided any details as to how many things you need in the child threads - if there aren't many, can you "extract" them in the request-scoped thread, and then pass them to you child threads "by hand"? (I note that this does slightly defeat the purpose of a DI framework...) – Andy Turner May 20 '16 at 07:37
  • "most" isn't everybody. A rough idea (without a guarantee that this actually works or is a good idea): create a custom scope that doesn't store it's objects in thread locals but merely the key for a shared threadsafe map that stores them. Then set the key in all threads that need to share the scope. That should lift the limitation that transfers have. Also make your scoped objects thread-safe, it's not guice that makes them unsafe. – zapl May 20 '16 at 07:49
  • 1
    See my answer to http://stackoverflow.com/q/20505649/502399 – Tavian Barnes May 20 '16 at 18:53
  • Everything is saved in thread-local variables. Spring is the same way... it's really annoying. What every you do, it'll be ugly. You'll probably need to pass variables around through parameters as soon as you fork off of your request thread... – Isaiah van der Elst May 20 '16 at 22:29
  • Thank @TavianBarnes!! I had played around with #continueRequest(), but they've marked it as deprecated in Guice 4 - they assume people want to #transferRequest() instead (we don't). We are *really* close to the first dot-point from your post. We bootstrap a jax-rs request object into a request-scoped provider before creating the rest of our graph. This way, providers for request scoped objects can directly inject the jax-rs request to get what they need. i.e. Using continueRequest(), we could simply seed with the request object and let guice re-compute the rest :) – phippsnatch May 21 '16 at 01:03
  • 1
    @phippsnatch Indeed, the Guice devs' view on that is ["If continueRequest is working for you, no reason to stop using it... but be aware that it makes it easy to accidentally access mutable objects from many threads at once."](https://github.com/google/guice/pull/974#discussion-diff-48865971). – Tavian Barnes May 21 '16 at 01:07
  • Cheers @TavianBarnes - much appreciated. – phippsnatch May 21 '16 at 02:15

0 Answers0