I don't really blog anymore. Click here to go to my main website.

muhuk's blog

Nature, to Be Commanded, Must Be Obeyed

May 02, 2015

Socko - An Embedded Web Server Written in Scala

Socko is a library that provides a web server which talks Akka with the rest of the application. I am not sure about the lightweight claim on its website, but it certainly delivers on the embedded claim. Just add it as a dependency and create a WebServer. You are not forced to use a special command-line tool. You are not forced to use a specific build tool. This is but important because I am interested in technologies that provide functionality without dominating my architecture.

Socko provides Akka extensions related to web servers, like like a static content handler and a REST handler. I haven’t used the REST stuff yet, but configuring a router with the static content handler is quite easy[1].

While it cooperates and augments Akka, Socko in my opinion isn’t really integrated with Akka. WebServer is not an actor. You write to responses and websocket connections instead of sending messages. You must make sure you are not sending a HttpResponseMessage to a remote actor. Because you can’t write to the response in another JVM. It breaks Akka’s design once, deploy any way you wish principle. I suppose you can hold onto request events until a response message arrives or use ask pattern to hide this irregularity.

One thing I stuggled with was injecting dependencies. Pretty much every component creates instances in its constructor, WebServer, ActorSystem, ActorRefFactory.actorOf[2]. I ended up creating an artificial graph comprising services and factories to delay instantialization of hard dependencies during injection. By the way, WebServer doesn’t manage the actor system, during shutdown you need to stop the actor system yourself.

Some Tips For Beginners

In the code examples creating one actor per request is suggested. Even if creating akka actors are cheap, it doesn’t make a lot of sense to create one just to process one message[3].

Akka configuration in configuration files override configuration done in code. I would suggest doing minimal amount of configuration in the code and keep as much of it in the configuration files. It might make sense for an actor to configure its children in code but it still can be overridden in configuration files.

The example for StaticContentHandler uses a magic constant to identify the dispatcher. Instead you can remove it from the code and define it in the config. Similarly router designations can be removed from the code and defined in the config. Perhaps you don’t even need a router (and a custom dispatcher) in development.

With these simplifications, this code:

val staticContentHandlerRouter = actorSystem.actorOf(
    Props(new StaticContentHandler(handlerConfig))
        .withRouter(FromConfig())
        .withDispatcher("my-pinned-dispatcher"),
    "static-file-router"
)

…becomes:

val staticContentHandlerRouter = actorSystem.actorOf(
    FromConfig.props(Props(classOf[StaticContentHandler], handlerConfig)),
    "static-file-router"
)

And the configuration to add is:

akka.actor.deployment {
    /static-file-router {
        dispatcher = my-pinned-dispatcher
    }
}

I’m not sure if you should bet your startup on Socko. But you can definitely check it out if you are shopping for an open source embedded web server. Socko is using permissive Apache License.


[1]You should use a high performance web server (like nginx) to serve your static content and only forward dynamic requests to your application. But StaticContentHandler is still very useful during development and QA.
[2]Therefore creating actors have side-effects. To be fair, Props can be injected. You just need to delay actorOf calls during object graph creation.
[3]And according to this answer top level actors have a greater cost. As far as I know, Future’s are preferred over actors for one off tasks. And actors make sense because they are stateful.

If you have any questions, suggestions or corrections feel free to drop me a line.