Библиотеки 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, потому что они действительно не сливаются с распределенными системами. Они работают только в четко разделенных разделах.