Sigo recibiendo opiniones contradictorias sobre la práctica de almacenar información en el Thread.current
hash (por ejemplo, el actual_usuario, el subdominio actual, etc.). La técnica se ha propuesto como una forma de simplificar el procesamiento posterior dentro de la capa del modelo (alcance de consultas, auditoría, etc.).
- ¿Por qué mis variables de hilo son intermitentes en Rails?
- Alternativa al uso de Thread.current en API wrapper para Rails
- ¿Son seguros los valores Thread.current [] y los atributos de nivel de clase para usar en rieles?
Muchos consideran que la práctica es inaceptable porque rompe el patrón MVC. Otros expresan preocupaciones sobre la confiabilidad / seguridad del enfoque, y mi pregunta de dos partes se enfoca en el último aspecto.
¿Se
Thread.current
garantiza que el hash esté disponible y sea privado para una sola respuesta, durante todo su ciclo?Entiendo que un hilo, al final de una respuesta, bien puede ser entregado a otras solicitudes entrantes, filtrando así cualquier información almacenada en
Thread.current
. ¿Sería suficiente borrar dicha información antes del final de la respuesta (por ejemplo, ejecutandoThread.current[:user] = nil
desde un controladorafter_filter
) para prevenir tal violación de seguridad?
¡Gracias! Giuseppe
fuente
Respuestas:
No hay una razón específica para mantenerse alejado de las variables locales del hilo, los problemas principales son:
Entonces, aunque no está completamente fuera de lugar su uso, el mejor enfoque es no usarlos, pero de vez en cuando te topas con una pared donde un hilo local será la solución más simple posible sin cambiar mucho código y tendrá que comprometerse, tener un modelo orientado a objetos menos que perfecto con el hilo local o cambiar bastante código para hacer lo mismo.
Por lo tanto, es principalmente una cuestión de pensar cuál será la mejor solución para su caso y si realmente va por el camino local del hilo, seguramente le aconsejaría que lo haga con bloques que recuerden limpiar después están hechos, como los siguientes:
around_filter :do_with_current_user def do_with_current_user Thread.current[:current_user] = self.current_user begin yield ensure Thread.current[:current_user] = nil end end
Esto asegura que la variable local del subproceso se limpie antes de usarse si este subproceso se recicla.
fuente
ensure
bloque y no intenta capturar la excepción.Esta pequeña joya garantiza que las variables locales de su hilo / solicitud no se queden entre solicitudes: https://github.com/steveklabnik/request_store
fuente
La respuesta aceptada cubre la pregunta, pero como Rails 5 ahora proporciona una " superclase abstracta" ActiveSupport :: CurrentAttributes que usa Thread.current.
Pensé que proporcionaría un enlace a eso como una posible solución ( impopular ).
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/current_attributes.rb
fuente
La respuesta aceptada es técnicamente precisa, pero como se señala en la respuesta con suavidad, y en http://m.onkey.org/thread-safety-for-your-rails no tan suavemente:
No use el almacenamiento local de subprocesos,
Thread.current
si no es absolutamente necesarioLa gema
request_store
es otra solución (mejor), pero solo lea el archivo Léame allí para obtener más razones para mantenerse alejado del almacenamiento local de subprocesos.Casi siempre hay una forma mejor.
fuente