83 votes

Sécurité d'utilisation de Thread.current [] dans les rails

Je reçois des avis divergents sur la pratique de stocker de l'information dans l' Thread.current de hachage (par exemple, la current_user, l'actuel sous-domaine, etc.). La technique a été proposée comme un moyen de simplifier le traitement ultérieur, à l'intérieur de la couche du modèle (requête d'établissement de la portée, de l'audit, etc.).

Beaucoup considèrent que la pratique inacceptable parce qu'il rompt le modèle MVC. D'autres expriment des préoccupations au sujet de la fiabilité/sécurité de l'approche, et mes 2 partie de la question porte sur ce dernier aspect.

  1. Est l' Thread.current de hachage garanties disponibles et privé à une seule et unique réponse, tout au long de son cycle?

  2. Je comprends qu'à un fil, à la fin d'une réponse, peut-être remis à d'autres demandes entrantes, ce qui les fuites de toutes les informations stockées dans Thread.current. Serait de compensation de ces informations avant la fin de la réponse (par exemple en exécutant Thread.current[:user] = nil à partir d'un contrôleur after_filter) suffit pour empêcher la violation de la sécurité?

Merci! Giuseppe

53voto

Maurício Linhares Points 19468

Il n'y a pas de raison particulière de rester loin de ces variables, les principaux enjeux sont:

  • il est plus difficile de les tester, que vous aurez à retenir pour définir les variables lorsque vous testez le code qui l'utilise
  • les classes qui utilisent fil les habitants auront besoin de connaître que ces objets ne sont pas disponibles pour eux, mais à l'intérieur d'une variable locale de thread et ce genre d'indirection généralement les sauts de la loi de déméter
  • pas de nettoyage du fil-des locaux peut être un problème si votre cadre réutilise les threads (thread-variable locale serait déjà entamé, et le code qui s'appuie sur ||= appels pour initialiser des variables peut échouer

Ainsi, même s'il n'est pas totalement hors de question d'utiliser la meilleure approche est de ne pas les utiliser, mais de temps en temps vous frappez un mur où un thread local va être le plus simple possible solution sans changer beaucoup de code et vous aurez à faire des compromis, ont un moins que parfait modèle orienté objet, avec le fil local ou de changer beaucoup de code pour faire la même chose.

Donc, c'est surtout une question de réflexion qui va être la meilleure solution pour votre cas et si vous êtes vraiment en descendant le fil-chemin d'accès local, je serais sûrement vous conseille de le faire avec des cubes n'oubliez pas 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 le fil de variable locale est nettoyé avant d'être utilisés si ce fil est recyclé.

24voto

Dejan Simic Points 2634

Ce petit bijou garantit à votre thread / requête que les variables locales ne collent pas entre les requêtes: https://github.com/steveklabnik/request_store

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X