Friday, November 27, 2009

Concurrently initialized singletons in Guice

William Pietri asked whether it would be possible to take advantage of concurrency and Guice's knowledge of dependencies to provide interdependent (and expensive to create) singleton services in parallel.

For example, say that service A depends on services B and C and that B and C don't know about each other (and so could be constructed concurrently). Obviously, you could explicitly construct B and C in separate tasks running in a thread pool, then construct A once B and C exist.

class A {
    A(B b, C c) { /* ... use b and c ... */ }
}

class B {
    B() { /* ... takes a long time ... */ }
}

class C {
    C() { /* ... takes a long time ... */ }
}

class Services {
    A a; B b; C c;
    void init() throws InterruptedException {
        final CountDownLatch ready = new CountDownLatch(2);
        Executor pool = Executors.newCachedThreadPool();
        pool.execute(new Runnable() {
            public void run() { b = new B(); ready.countDown(); }
        })
        pool.execute(new Runnable() {
            public void run() { c = new C(); ready.countDown(); }
        })
        ready.await();
        a = new A(b, c);
        // Now publish a, b, and c safely -- not shown.
    }
}

But it's a pain to have to orchestrate this yourself. You have to know the dependencies intimately and write a lot of tricky code. If the dependencies change, the code has to be completely rethought. Wouldn't it be nice if Guice could do this for you automatically without giving up on the opportunities for concurrency? Well, it turns out that it can.

The idea is to use a variant of singleton scope that runs the providers of all bindings for that scope in separate threads. Naturally some of these providers block in their own thread while their dependencies finish in other threads, but those services that can be constructed in parallel will be.

Here's what the Guice version looks like:

@ConcurrentSingleton
class A {
    @Inject A(B b, C c) { /* ... use b and c ... */ }
}

@ConcurrentSingleton
class B {
    @Inject B() { /* ... takes a long time ... */ }
}

@ConcurrentSingleton
class C {
    @Inject C() { /* ... takes a long time ... */ }
}

No special initialization code needed, just inject A, B, and C wherever they are needed. (Note that if you have circular dependencies, this probably won't work. So don't have circular dependencies.)

ConcurrentSingleton is just a scope annotation. The actual scope implementation is ConcurrentSingletonScope. I have a fleshed-out version of the A, B, C example, ConcurrentSingletonExample, that is slightly different from the code above; it uses Providers for B and C so that A can do some work before getting B and C in the constructor.

You aren't forced to do all the expensive work in the constructor. You could also inject a start method with injected parameters to provide needed dependencies.

In the same thread that provoked the ConcurrentSingleton response, Jesse Wilson suggested the use of the experimental lifecycle facility in Guava. This could prove useful in the current context if, for example, you have singleton services that take a while to stop and could benefit from being stopped in parallel.

Update 2009-11-30
I added a call to pool.shutdown() in the scope implementation to make sure the pool threads don't prevent the JVM from exiting. It might not be necessary, but I don't think it hurts.

Update 2010-7-3
Added explicit notice that the sources are in the public domain.

Monday, October 26, 2009

The Emperor's New Clothes

I posted Ray Mason's video of The Emperor's New Clothes, a Theatre Three Children's Theatre production of a show that Jeff Sanzel and I wrote together, on my Facebook profile and my YouTube channel, broken up into scene length segments.

See the links section in the right-hand column -- you'll want to look at the YouTube version unless you're my Facebook friend, and even then you might prefer to watch the YouTube playlist, something for which there is no analogue in Facebook ... is there?

I haven't bothered to post to MySpace this time around.

Friday, September 11, 2009

Joshua Rosenblum's site

Josh Rosenblum has a website worth checking out:

http://rosenblummusic.com

The site was designed and implemented by Josh's 13-year-old son, Julian.

And don't be afraid to go ahead and buy those albums! :-)

Tuesday, May 12, 2009

Dependency injection in Restlet 2.0 with Guice

I'm very excited about Restlet 2.0, which is in testing now and scheduled for release at the end of 2009. Among other things, the newly refactored Resource API encourages more readable code through the use of a small number of annotations. Here's a very simple server-side resource:
public class DefaultResource extends ServerResource {
    @Get public String represent() {
        return "Default resource, try /hello/resource or /hello/handler";
    }
}

ServerResource has a no-arg constructor, so you don't need to pass Context, Request, and Response objects to super().

Nice as this is, I still want to inject my resources using Guice, so I've updated the Restlet-Guice classes from my previous post to support both the new ServerResources and the old Handlers. It incorporates the enhancement mentioned in the updates: You can override methods to use different providers for Application, Context, Request, and Response, although for most purposes the default providers should suffice.

Update 2009-Dec-11


I've been working on a Guice extension for Restlet as an incubator project that uses the ideas in this posting. My goal is to make this extension independent of Guice at the interface level, so that people can provide implementations for different DI frameworks, of which Guice is only the first.