Sunday, February 24, 2008

MINA bindings for Scala (updated)

I've just updated the bindings again, so I thought it was a good opportunity to write about some of the things that have happened since my last post.

First, the bindings are now hosted on their own project website. The website includes a Mercurial repository that contains a mirror of MINA's trunk along with a branch for the bindings. I've received some encouragement from MINA committers, so there's also a ticket on the Apache JIRA site with patches that might one day make it into MINA proper.

Second, the bindings now provide a full interface for MINA's IoSession, including all its subclasses and configuration options. I've written Scala wrappers for a few other classes, but the rest of the library already works quite well from Scala without any wrapping.

Third, I've rewritten most of the code. This is most obvious when you look at what has happened to the ActorIoHandler class that I introduced in my previous post.

Originally, the ActorIoHandler class did three things:

  1. It associated each IoSession with an actor.
  2. It translated IoHandler events into messages for each actor.
  3. It intercepted the sessionCreated event and sent it to a separate "serviceHandler" actor, so that applications would have a place to hook in their handling code for each session.

The ActorIoHandler class has now gone, and its three behaviours have been factored out:

  1. Associations between IoSessions and their actors are now handled by a single method: IoSessionActor.getAssociatedActor(). This method is marked with the implicit keyword so that, by importing the method, the translation between session and actor can happen automatically (which is very useful). Also, we're able to secretly cache the actor in a session attribute, whichs means that we will only ever create one actor for a given session.
  2. IoHandler events are now sent to each session actor via the singleton IoSessionActor.relayHandler. Compared to the previous ActorIoHandler, the relayHandler is delightfully simple. When it receives an event, it uses the standard IoSessionActor.getAssociatedActor() method to get the actor for a session, then it just creates an object to represent the event and sends it to the actor.
  3. Notifying applications about new sessions is no longer the concern of the IoHandler. Now, you can receive these notifications, on an OutputChannel of your choosing, by creating a ChannelingIoServiceListener.

Actually, the previous mixed-up behaviour of ActorIoHandler was useful in some ways, because all three behaviours really are needed if you want your application work session actors. Luckily, this mixture is still catered for. Now you just need to call IoSessionActor.installHandling(), passing along an IoService and a your own "handler" function. Your handler function will be started in a fresh actor for each session, then passed the session as an argument - easy.

That pretty much covers progress since my last post. If you want to have a play, you'll need to checkout the code and run Maven. Unfortunately I haven't written any documentation (yet!), so the examples are still the best place to look to get started. Let me know if you have any questions; I'm happy to help.