В нашей системе наши регистраторы используют MD C для передачи информации. Это хорошо, если у вас нет сценариев использования с логическими потоками c между потоками, но, к сожалению, это реальность современной разработки программного обеспечения.
Я придумал следующее решение, которое мы могли бы использовать в качестве оболочки для нашего глобального пула потоков (методы Logger / MD C вымышлены и предназначены только для иллюстративных целей):
class MDCAwareExecutionContext(ec: ExecutionContext) extends ExecutionContext {
override def execute(runnable: Runnable): Unit = {
val mdc: java.util.Map[_, _] = Logger.getMDCValues()
ec.execute(() =>
Logger.clearMDCValues()
Logger.setMDCValues(mdc)
runnable.run()
)
}
override def reportFailure(cause: Throwable): Unit =
ec.reportFailure(cause)
}
Но мой коллега упомянул, что в прошлом он пробовал что-то подобное и что, исходя из эмпирического опыта, это не сработало. Вместо этого он предложил альтернативу, основанную на ExecutionContext.prepare()
, которая объявлена устаревшей. У меня нет причин думать, что он не прав, но, с другой стороны, я не понимаю, что может go ошибиться в моем примере.
Есть ли какая-то причина, почему это не сработало бы так, как задумано в Scala? Я бы предположил, что вне будущего мы все еще в состоянии правильно захватить MD C, и что внутри будущего мы уже в произвольном потоке, но всегда безопасно читать переменную originalMdc
. Я упускаю какую-то неясную возможность?
Спасибо