Actually, it's worse than that: Even with a latch, the Guice internals are so aggressively single-threaded that this approach doesn't work at all -- the trivial demonstration only works because of the uninjected custom provider. What a shame.
Sorry if I got any hopes up. :-( --tim On Nov 20, 12:00 am, Tim Peierls <tpeie...@gmail.com> wrote: > Hmm, I'm not sure if the Guice internals are safe to access from other > threads during calls to scope(Key, Provider) -- maybe a Guiceru can > tell us. If not, this approach would have to be tweaked to ensure that > the submitted tasks all wait on a latch that gets opened as soon as it > is safe to proceed. > > --tim > > On Nov 19, 11:48 pm, Tim Peierls <tpeie...@gmail.com> wrote: > > > > > I've sketched an approach here that might work for > > you:http://pastie.org/707072 > > > The idea is that ConcurrentSingletonScope, when the injector is > > created, eagerly starts computing in background the instances it will > > eventually provide. The background threads are in a cached thread > > pool, which creates new threads when needed. This approach probably > > will deadlock if there are circular dependencies -- but creating > > circular dependencies is a bad idea to begin with. > > > The main routine in the code demonstrates, somewhat artificially, that > > the provision happens in parallel. In practice, you would not use > > explicit Provider instances in this way. > > > If this were to be adapted for production use, you'd want to add a > > scope annotation and bind it to ConcurrentSingletonScope, so you'd be > > able to say something like: > > > @ConcurrentSingleton > > public class MyExpensiveStartupService { > > @Inject public MyExpensiveStartupService( > > Provider<MyExpensiveDep1> myExpDep1Provider, > > Provider<MyExpensiveDep2> myExpDep2Provider) { > > // Copy parameters to final fields. > > } > > @Inject public void start() { > > // Do something expensive. > > expensiveStuff(); > > > // Now make use of my expensive-to-compute dependencies. > > // They might already be available, but if not, we block until > > they are. > > MyExpensiveDep1 myExpDep1 = myExpDep1Provider.get(); > > MyExpensiveDep2 myExpDep2 = myExpDep2Provider.get(); > > makeUseOf(myExpDep1, myExpDep2); > > } > > > } > > > --tim > > > On Nov 18, 7:20 pm, William Pietri <will...@scissor.com> wrote: > > > > Hi! I am trying to decide if Guice would help a problem. > > > > I'm investigating a problem with startup times in a server app. At > > > launch, the app creates a root object with a few dozen services, with > > > inter-service dependencies injected manually. A number of these > > > services are very expensive (minutes to create, much RAM used). > > > Mapping out the dependencies, it looks like starting things up is > > > happily parallelizable, but sorting out the relationships and stages > > > manually is a bit of a pain. > > > > That pain is the sort of thing that Guice was created to solve. > > > However, in the archives, I see mention that Guice single-threads the > > > creation of Singletons, which sounds like it would prevent me from > > > parallelizing service startups. > > > > Is there some way I can use Guice to automatically bind together my > > > many expensive services in a way that takes advantage of the idle > > > cores on my servers? > > > > Thanks, > > > > William -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to google-gu...@googlegroups.com. To unsubscribe from this group, send email to google-guice+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-guice?hl=.