Je continue à obtenir des opinions contradictoires sur la pratique du stockage d'informations dans le Thread.current
hachage (par exemple, l'utilisateur actuel, le sous-domaine actuel, etc.). La technique a été proposée comme un moyen de simplifier le traitement ultérieur au sein de la couche modèle (portée de requête, audit, etc.).
Beaucoup considèrent la pratique inacceptable car elle rompt le modèle MVC. D'autres expriment des préoccupations quant à la fiabilité/sécurité de l'approche, et ma question en deux parties se concentre sur ce dernier aspect.
Est le Thread.current
hash garanti d'être disponible et privé pour une et une seule réponse, tout au long de son cycle?
Je comprends qu'un thread, à la fin d'une réponse, pourrait bien être remis à d'autres demandes entrantes, ce qui ferait fuir toute information stockée dans Thread.current
. Voudrait effacer ces informations avant la fin de la réponse (par exemple en exécutant Thread.current[:user] = nil
d'un contrôleur after_filter
) suffit-il pour empêcher une telle atteinte à la sécurité?
Merci! Giuseppe
Il n'y a pas de raison spécifique de rester à l'écart des variables locales de thread, les principaux problèmes sont les suivants:
Donc, bien qu'il ne soit pas complètement hors de question d'utiliser, la meilleure approche n'est pas de les utiliser, mais de temps en temps vous heurtez un mur où un le thread local va être la solution la plus simple possible sans changer beaucoup de code et vous devrez faire des compromis, avoir un modèle orienté objet moins que parfait avec le thread local ou changer pas mal de code pour faire de même.
Donc, c'est surtout une question de réflexion qui va être la meilleure solution pour votre cas et si vous suivez vraiment le chemin du thread local, je vous conseillerais sûrement de le faire avec des blocs qui se souviennent de nettoyer après ils sont faits, comme suit:
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
Cela garantit que la variable locale du thread est nettoyée avant d'être utilisée si ce thread est recyclé.
Ce petit bijou garantit que vos variables locales de thread/requête ne collent pas entre les requêtes: https://github.com/steveklabnik/request_store
La réponse acceptée couvre la question mais comme Rails 5 fournit maintenant une "super classe abstraite" ActiveSupport :: CurrentAttributes qui utilise Thread.current.
J'ai pensé que je fournirais un lien vers cela comme une solution possible ( impopulaire ).
https://github.com/Rails/rails/blob/master/activesupport/lib/active_support/current_attributes.rb
La réponse acceptée est techniquement exacte, mais comme indiqué dans la réponse doucement et dans http://m.onkey.org/thread-safety-for-your-Rails pas si doucement:
N'utilisez pas le stockage local des threads, Thread.current
si vous n'êtes pas obligé
Le bijou pour request_store
est une autre solution (meilleure) mais lisez simplement le fichier Lisez-moi pour plus de raisons de ne pas utiliser le stockage local des threads.
Il y a presque toujours une meilleure façon.