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.

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 on the left -- 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.

Still no fancy packaging, just a zip archive of source that you can compile against Restlet 2.0 and Guice 1.0 (it would probably work with Guice 2, but I haven't tried).

Monday, December 15, 2008

Musical numbers from my shows

After years of vague promises to cast members to provide a record of the shows that Jeff Sanzel and I have written together for Theatre Three children's theatre productions, I finally got up my courage to edit together the tapes I'd made into more or less coherent individual musical numbers. I've been posting them to YouTube, Facebook, and MySpace as I finish them.

The tapes were made by setting up a camera (or two) before each performance, pointing it towards the stage, turning it on, and leaving it there unattended. In some cases I also recorded a separate audio track with a decent stereo mic. There are several problems with this approach:
  • The camera is stationary, so any zooming or panning has to be applied after the fact. This makes for blurry closeups.

  • The autofocus is often confused by stage lighting changes.

  • Each performance is slightly different, so synching lip movements can be tricky. I got it wrong in several instances.

  • The mic in the camera is not as good as the separate stereo mic, and the sound quality varies depending on where the camera is placed. So only The Fairy Princess has good sound.

But I hope the end results are entertaining, if only for the performers who took part in the productions.

Eventually I'd like to create a video or sequence of videos covering an entire show, for watching in a YouTube playlist, for example. I made studio recordings of Hansel and Gretel and The Fairy Princess (and I hope to do so for The Elves and the Shoemaker), so it is possible that I could use that material for the soundtrack.

Thursday, September 25, 2008

New CD: "Colloquy"

I am once more proud to announce the release of a CD that I produced: Colloquy, an album of music by Gary William Friedman. And once more, I am several weeks late in my announcement. Maybe I planned it that way. Yeah, that's it.

I wrote the liner notes for this album, and I won't repeat them here, so go get a copy and read them. Or don't read them, just listen to the music -- I don't mind.

Update:

There's also a video about the making of one of the pieces on the album.

Thursday, July 24, 2008

New CD: "Before Love Has Gone"

I'm proud to announce the release, one month ago, of a new album from Stevie Holland, Before Love Has Gone, that I co-produced with Todd Barkan and Gary William Friedman. (The actual release date was June 24, but I kept forgetting to blog about it and decided to wait out the full month.)

Go get it and listen to it. The whole album is great, but if you're really stingy and can only spring for one tune, I recommend "Lazy Afternoon". It's phenomenal.

Update:

There's also an EPK for the album.

Resource dependency injection in Restlet via Guice

(See a more recent posting on this subject.)

I have a body of code that already benefits from Guice dependency injection, and I want to migrate it from a servlet-based architecture to Restlet without losing those benefits. I've had some success, and I figured I'd report on it.

I don't mean that I wanted to use Guice to wire up an object graph of Restlets (Components, VirtualHosts, Applications, etc.). It's straightforward enough to use the builder-like API of Restlet, and such code is nicely confined in a few places where it doesn't bother the meat of the application, its resources.

What I do want is to have those resources created by Guice, so that they can be constructed with dependencies injected into them. With the Finder approach, resource constructors get a Context, a Request, and a Response, but that's it. I suppose I could find a way to stash an Injector in one of these so that resources could look up the dependencies they need, but I wanted something more direct. I came up with the following scheme, which seems to be working pretty well:

I use a custom Finder that knows how to look up a Handler/Resource by class or Guice key -- instances of these custom Finders are provided by a FinderFactory:

public interface FinderFactory {
Finder finderFor(Key<? extends Handler> key);
Finder finderFor(Class<? extends Handler> cls);
}

The class RestletGuice has static methods named createInjector that parallel those of the Guice class. The difference is that it adds bindings for Context, Request, Response, and FinderFactory. In my Guiced version of the FirstStepsApplication from restlet.org, the following lines create an Injector with some bindings and then look up the FinderFactory that will produce Finders that will be able to make use of those bindings. (These bindings are not necessarily good practice; they just demonstrate the technique.)

Injector injector = RestletGuice.createInjector(new AbstractModule() {
public void configure() {
bind(Handler.class)
.annotatedWith(HelloWorld.class)
.to(HelloWorldResource.class);
bindConstant()
.annotatedWith(named(HelloWorldResource.HELLO_MSG))
.to("Hello, Restlet-Guice!");
}
});
FinderFactory factory = injector.getInstance(FinderFactory.class);

HelloWorldResource is slightly changed. It has a private final field, msg, that is used to generate the text representation. The msg field is initialized via an injected value.

@Inject public HelloWorldResource(@Named(HELLO_MSG) String msg,
Request request,
Response response,
Context context) {
super(context, request, response);
this.msg = msg;
getVariants().add(new Variant(MediaType.TEXT_PLAIN));
}
static final String HELLO_MSG = "hello.message";

This all comes together in the Application class when attaching a Finder for the default routing.

Finder finder = factory.finderFor(Key.get(Handler.class, HelloWorld.class));
Router router = new Router(getContext());
router.attachDefault(finder);
return router;

I read this as "Route any request for this application to whatever resource is bound to @HelloWorld-annotated Handlers, injecting that resource's dependencies," which was exactly what I wanted.

For those who don't want to have to call a special RestletGuice method, there is a public class FinderFactoryModule extending AbstractModule that can be used with Guice.createInjector(...) to get the same effect.

FinderFactoryModule also implements FinderFactory, so you can construct an instance in your Restlet wiring code and use it right away. You can then use the FinderFactoryModule to create an injector explicitly.

As a special convenience, if you don't use a FinderFactoryModule to create an injector, one will be created implicitly the first time one of its Finders is used to find a target Handler/Resource. This encourages a style where each Application gets its own implicit Injector by creating a local FinderFactoryModule and using it to create Finders.

That's basically it. It works with plain Guice 1.0 and Restlet 1.1 (since it uses Handler as the base type for all Resources). I haven't had time to package it nicely, but you can follow the links below for the actual code.

Sources:
FinderFactory.java
FinderFactoryModule.java
RestletGuice.java

Example:
FirstStepsApplication.java
HelloWorld.java
HelloWorldResource.java
Main.java

Update (August 2008)


Chris Lee discovered that Context.getCurrent() doesn't work reliably as of 1.1m5; the workaround is to use Application.getCurrent().getContext(). A more comprehensive fix, that I hope to post soon, would involve letting subclasses of FinderFactoryModule override the methods that create the Providers for Request, Response, and Context.

Update (2009-Feb-3)


Leigh Klotz has a workaround for using Guice Finders with WadlApplication. And I still haven't had time to package any of this more nicely. (Feb 7: Jérôme Louvel took Leigh's suggestion and checked it in on the Restlet trunk.)