Библиотеки Akka и Java, которые используют ThreadLocals

Что мешает мне использовать Akka регулярно (на Java), это проблема, с которой я сталкиваюсь с библиотеками, использующими ThreadLocals.

То есть, я думаю, что некоторые диспетчеры Akka могут вызывать переменные ThreadLocal, или же не все вместе. Поэтому очевидным решением было бы избежать использования ThreadLocals, но есть так много библиотек, которые их используют: Spring, Wro4j, Log4j и т.д. И т.д.

ThreadLocals нормально работают в контейнере сервлетов. Это связано с тем, что хотя контейнеры имеют threadpools, запрос в основном представляет собой синхронный жизненный цикл, поэтому, как правило, в конце запроса такие вещи, как Spring и Wro4J, будут очищать там threadlocals. Некоторые контейнеры, такие как Tomcat, даже контролируют токлокальные утечки.

В Акке это не так, как я понимаю.

Как люди могут обойти эту проблему?

На данный момент я просто не использую Akka и использую Message Queue (например, RabbitMQ или ActiveMQ), но хотел бы использовать Akka, поскольку он охватывает более широкий спектр проблем/решений async.

Я также думаю, что Netty имеет схожие проблемы, но я считаю, что Netty предлагает какой-то объект Context Channel Context, который вы можете использовать вместо ThreadLocal, и теоретически некоторые библиотеки могут знать, что использовать это вместо ThreadLocal.

Ответ 1

Самый простой способ его решения - разграничить использование ThreadLocals, поэтому вы создаете метод как таковой:

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

Затем внутри вашего Актера или еще чего-то:

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

В общем, я бы избегал ThreadLocals, потому что они действительно не сливаются с распределенными системами. Они работают только в четко разделенных разделах.