scala thread-local

¿Cuándo deberíamos usar scala.util.DynamicVariable?



thread-local (3)

Este es un fragmento mínimo:

val dyn = new DynamicVariable[String]("withoutValue") def print=println(dyn.value) print dyn.withValue("withValue") { print } print

El resultado será:

withoutValue withValue withoutValue

Cuando leí la fuente de scalatra, encontré que hay algunos códigos como:

protected val _response = new DynamicVariable[HttpServletResponse](null) protected val _request = new DynamicVariable[HttpServletRequest](null)

Hay una clase interesante llamada DynamicVariable . He visto el documento de esta clase, pero no sé cuándo ni por qué deberíamos usarlo. Tiene un withValue() que generalmente se usa.

Si no lo usamos, ¿qué código deberíamos usar para resolver el problema resuelto?

(Soy nuevo en Scala, si puedes proporcionar algún código, será genial)


Vasil lo responde bien, pero agregaré un ejemplo simple adicional que podría ayudar a comprender mejor.

Supongamos que debemos usar algún código que use println () para escribir todo sobre stdout. Queremos que esta salida vaya a un archivo de registro, pero no tenemos acceso a la fuente.

  • println() usa Console.println()
  • Console.println() (afortunadamente) se basa en DynamicVariable[PrintStream] que por defecto es java.lang.System.out
  • Console define withOut que simplemente reenvía a la variable dinámica withValue

Podemos usar esto para simplemente arreglar nuestro problema:

def noisy() { println("robot human robot human") } noisy() // prints to stdout val ps = new java.io.PrintStream("/tmp/mylog") scala.Console.withOut(ps) { noisy() } // output now goes to /tmp/mylog file


DynamicVariable es una implementación del préstamo y los patrones de alcance dinámico. Use-case de DynamicVariable es bastante similar a ThreadLocal en Java (de hecho, DynamicVariable usa InheritableThreadLocal detrás de las escenas) - se usa cuando se necesita hacer un cálculo dentro de un alcance cerrado, donde cada hilo tiene su propia copia del valor de la variable:

dynamicVariable.withValue(value){ valueInContext => // value used in the context }

Dado que DynamicVariable usa un ThreadLocal heredable, el valor de la variable se pasa a los hilos generados en el contexto:

dynamicVariable.withValue(value){ valueInContext => spawn{ // value is passed to the spawned thread } }

DynamicVariable (y ThreadLocal ) se usa en Scalatra por la misma razón que se usa en muchos otros marcos (Lift, Spring, Struts, etc.): es una forma no intrusiva de almacenar y transmitir información específica de contexto (hilo).

Hacer las variables dinámicas HttpServletResponse y HttpServletRequest (y, por lo tanto, vinculante a un hilo específico que procesa la solicitud) es simplemente la forma más fácil de obtenerlas en cualquier parte del código (no pasando por los argumentos del método o de ningún otro modo explícito).