14

What has kept me from using Akka regularly (in Java) is a concern I have with libraries that use ThreadLocals.

That is I think some Akka Dispatchers may cause ThreadLocal variables to be left behind, or missing all together. So the obvious solution would be to avoid using ThreadLocals but there are so many libraries that use them: Spring, Wro4j, Log4j, etc etc...

ThreadLocals normally work fine in Servlet Container. That is because even though containers have threadpools the request is mainly a synchronous lifecycle, thus generally at the end of a request things like Spring and Wro4J will clean up there threadlocals. Some containers like Tomcat even monitor threadlocal leaks.

Such is not the case in Akka from what I understand.

How do people get around this issue?

For now I just avoid using Akka and use a Message Queue (like RabbitMQ or ActiveMQ) but would like to use Akka as it covers a wider range of async problem/solution.

I also think Netty has similar issues but I believe Netty offers some sort Channel Context object that you can use in place of ThreadLocal and in theory some libraries may know to use that instead of ThreadLocal.

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • 1
    What exactly are the concerns you have with ThreadLocals? Can you elaborate? – Alex Objelean Nov 03 '12 at 16:04
  • 2
    Lets say Spring binds a Transaction to a Thread because I did some sort of JDBC operation in an Actor then Akka essentially suspends that thread and hands it off to a different actor... you might get some weird behavior... or worse maybe the transaction never closes. Another example is Log4J and logback's MDC: https://groups.google.com/d/msg/akka-user/f5YDBKVExmQ/_mOOuQu2SXcJ – Adam Gent Nov 03 '12 at 17:01
  • @AlexObjelean for Wro4j its lets of an issue because its in the Request Thread and I don't think you have it so that it inherits into other threads (although I did have some trouble trying to get your library to work with Netty I eventually just did the asset pipeline myself avoiding wro4j's context object). – Adam Gent Nov 03 '12 at 17:17
  • I think you should not worry that much about ThreadLocal itself, rather than the sloppy usage of ThreadLocal: http://old.nabble.com/Threadlocals-and-memory-leaks-in-J2EE-td13097957.html#a13097957 – Alex Objelean Nov 03 '12 at 23:37

1 Answers1

3

The easiest way to solve it is to demarcate the use of ThreadLocals, so you create a method as such:

def withSecurityContext[T](thunk: => T)(implicit secCtx: SecurityContextFetcher): T = {
  val old = threadLocalSecurityContext.get
  threadLocalSecurityContext.set(secCtx.fetch)
  try thunk finally threadLocalSecurityContext.set(old)
}

Then inside your Actor or whatnot:

class MyActor extends Actor {
    def receive = {
      case "foo" => withSecurityContext { beAwesome() }
    }
}

In general though, I'd avoid ThreadLocals because they don't really blend in with distributed systems. They only work in clearly demarcated sections.

Viktor Klang
  • 26,479
  • 7
  • 51
  • 68
  • do you think it would be worthwhile for Akka to support some ThreadLocal leak detection like Tomcat does (perhaps on shutdown of Akka)? Maybe a little side project (porting Tomcat's detection) that I could do that would help assuage my fears :) – Adam Gent Nov 04 '12 at 17:30
  • 1
    Akka is open source, if you want to tackle this issue and submit a PullRequest I'll gladly consider including it! – Viktor Klang Nov 04 '12 at 20:51