J'essaie de bien comprendre les options de traitement des requêtes simultanées dans Rack. J'ai utilisé async_sinatra pour construire une application à longues requêtes, et j'expérimente maintenant avec Rack bare-metal en utilisant throw :async
et/ou le drapeau de Thin --threaded. Je suis à l'aise avec le sujet, mais il y a certaines choses que je n'arrive pas à comprendre. (Non, je ne confonds pas concurrence et parallélisme, et oui, je comprends les limitations imposées par la GIL).
Q1. Mes tests indiquent que thin --threaded
(c'est-à-dire rack.multithread=true
) exécute les requêtes simultanément dans des threads séparés (je suppose qu'il utilise EM), ce qui signifie qu'une requête A longuement exécutée ne bloquera pas la requête B (IO mis à part). Cela signifie que mon application n'a pas besoin d'un codage spécial (par exemple, des callbacks) pour obtenir la simultanéité (encore une fois, en ignorant les appels bloquants à la base de données, les E/S, etc.) C'est ce que je crois avoir observé - est-ce exact ?
Q2. Il existe un autre moyen, plus souvent discuté, de réaliser la concurrence, qui consiste à EventMachine.defer
y throw :async
. A proprement parler, les demandes sont no gérés à l'aide de threads. Elles sont traitées en série, mais transmettent le gros du travail et un callback à EventMachine, qui utilise async.callback pour envoyer une réponse à un moment ultérieur. Après que la demande A a déchargé son travail sur EM.defer, la demande B est lancée. Est-ce correct ?
Q3. En supposant que les réponses ci-dessus soient plus ou moins correctes, Y a-t-il un avantage particulier à une méthode plutôt qu'à une autre ? Évidemment --threaded
ressemble à une balle magique. Y a-t-il des inconvénients ? Si non, pourquoi tout le monde parle de async_sinatra
/ throw :async
/ async.callback
? Peut-être que la première option est "Je veux rendre mon application Rails un peu plus rapide en cas de forte charge" et que la seconde est mieux adaptée aux applications comportant de nombreuses requêtes de longue durée ? Ou peut-être l'échelle est-elle un facteur ? Je ne fais que supposer.
J'utilise Thin 1.2.11 sur MRI Ruby 1.9.2. (Pour info, je dois utiliser l'extension --no-epoll
car il y a un problème de longue date, prétendument résolu, mais qui ne l'est pas vraiment. avec l'utilisation d'epoll et de Ruby 1.9.2 par EventMachine. Cela n'a rien à voir avec le sujet, mais toute idée est la bienvenue).