Comment puis-je servir des requêtes en même temps que des Rails 4?
j'essaie de servir plusieurs requêtes simultanément dans les Rails 4, ce que j'ai pu faire très facilement avec config.threadsafe!
et Puma
dans les Rails 3.
Dire que j'ai ce contrôleur
class ConcurrentController < ApplicationController
def index
sleep 10000
end
def show
end
end
j'ai utilisé pour être en mesure de juste démarrer puma avec puma -t 2:16 -p 3000
(pour min 2 threads) et frapper index
et puis show
et ont encore show
rendre correctement.
dans les Rails 4, si je tente de faire le la même chose que Puma verrouille maintenant sur la demande index
et show
n'est jamais rendue. Quand j'appuie sur Ctrl-C
pour le serveur Puma me donne cette erreur:
Rack app error: #<ThreadError: Attempt to unlock a mutex which is locked by another thread>
Qu'est-ce que je manque ici pour obtenir la concurrence pour travailler avec Rails 4? config.threadsafe!
est supposé ne pas être nécessaire (et ne pas faire une différence, même si j'essaie)
3 réponses
je vous invite à lire les options de configuration de config.threadsafe!
dans cet article supprimer la configuration.des threads!
Il vous aidera à mieux comprendre les options de config.threadsafe!
, en particulier pour permettre la simultanéité.
dans les Rails 4 config.threadsafe!
est défini par défaut.
Maintenant, à la réponse
dans les Rails 4 demandes sont enroulées autour d'un Mutex par le Rack:: Lock middleware dans les environnements DEV par défaut.
Si vous voulez activer la simultanéité , vous pouvez définir config.allow_concurrency=true
. Cela désactivera le Rack::Lock middleware. Je ne le supprimerais pas comme mentionné dans une autre réponse à votre question; cela ressemble à un piratage pour moi.
Note : si vous avez
config.cache_classes=true
puis une affectation àconfig.allow_concurrency
(Rack::demande de Verrouillage mutex) ne prendra pas effet, les requêtes concurrentes sont autorisées par défaut. Si vous avezconfig.cache_classes=false
, alors vous pouvez définirconfig.allow_concurrency
àtrue
oufalse
. En DEV environnement vous voudriez l'avoir comme ceciconfig.cache_classes=false config.allow_concurrency=true
la déclaration: ce qui signifie que si config.cache_classes = false (qui est par défaut dans dev env), nous n'avons pas simultanées demande. n'est pas correct.
Annexe
vous pouvez vous référer à cette réponse , qui met en place une expérience tester la simultanéité en utilisant L'IRM et JRuby. Les résultats sont surprenants. L'IRM était plus rapide que JRuby.
l'expérience avec la simultanéité IRM est sur GitHub . L'expérience ne teste que les requêtes simultanées. Il n'y a pas de conditions de course dans le contrôleur. Cependant, je pense qu'il n'est pas trop difficile à appliquer l'exemple de l'article ci-dessus pour tester les conditions de course dans un contrôleur.
il semble que par défaut, dans les Rails 4, les requêtes concurrentes ne sont pas activées dans l'environnement de développement.
j'ai trouvé cette citation dans la documentation 151990920" .
Rack:: Lock enveloppe l'application dans mutex de sorte qu'il ne peut être appelé par un seul fil à la fois. Seulement activé quand config.cache_classes est faux.
, ce Qui signifie que si config.cache_classes = false
(qui est par défaut dans dev env) nous ne pouvons pas avoir de requêtes simultanées.
les requêtes simultanées fonctionnent avec mon exemple dans l'environnement de production.
une solution est de mettre config.cache_classes = true
dans l'environnement de développement, mais alors le code ne se recharge pas sur un changement, ce qui ne fonctionne pas vraiment pour le développement.
le deuxième type de solution hacky est de désactiver le Rack::Lock
middleware en développement.
donc si vous deviez ajouter development.rb
la ligne suivante:
config.middleware.delete Rack::Lock
vous devriez être en mesure d'avoir des requêtes concurrentes dans l'environnement de développement avec les classes de cache désactivées.
vous pouvez essayer de la licorne c'est très simple, le mode de développement: