web-dev-qa-db-fra.com

Comment Waitress gère-t-elle les tâches simultanées?

J'essaye de construire un serveur web python en utilisant Django et Waitress, mais j'aimerais savoir comment Waitress gère les requêtes simultanées, et quand un blocage peut se produire.


Bien que documentation Waitress mentionne que plusieurs threads de travail sont disponibles, il ne fournit pas beaucoup d'informations sur la façon dont ils sont implémentés et comment le python GIL les affecte ( accent le mien):

Lorsqu'un canal détermine que le client a envoyé au moins une requête HTTP valide complète, il planifie une "tâche" avec un "répartiteur de thread". Le répartiteur de threads maintient un pool fixe de threads de travail disponibles pour effectuer le travail client (par défaut, 4 threads). Si un thread de travail est disponible lorsqu'une tâche est planifiée, le thread de travail exécute la tâche. La tâche a accès au canal et peut réécrire dans le tampon de sortie du canal. Lorsque tous les threads de travail sont en cours d'utilisation , les tâches planifiées patienteront dans une file d'attente pour qu'un thread de travail devienne disponible.

Il ne semble pas non plus y avoir beaucoup d'informations sur Stackoverflow. De la question "L'employé asynchrone gthread de Gunicorn est-il analogue à Waitress?" :

Waitress a un thread async principal qui met en mémoire tampon les demandes et met chaque demande en file d'attente dans l'un de ses threads de travail de synchronisation lorsque l'E/S de la demande est terminée.


Ces déclarations ne concernent pas le GIL (du moins d'après ce que je comprends) et ce serait formidable si quelqu'un pouvait en dire plus sur le fonctionnement des threads de travail pour Waitress. Merci!

9
MoltenMuffins

Voici comment fonctionnent généralement les serveurs asynchrones pilotés par les événements:

  • Démarrez un processus et écoutez les demandes entrantes. En utilisant l'API de notification d'événements du système d'exploitation, il est très facile de servir des milliers de clients à partir d'un seul thread/processus.
  • Puisqu'il n'y a qu'un seul processus gérant toutes les connexions, vous ne voulez pas effectuer de tâches lentes (ou bloquantes) dans ce processus. Parce qu'alors, il bloquera le programme pour chaque client.
  • Pour effectuer des tâches de blocage, le serveur délègue les tâches aux "travailleurs". Les ouvriers peuvent être des threads (exécutés dans le même processus) ou des processus distincts (ou sous-processus). Désormais, le processus principal peut continuer à servir les clients pendant que les travailleurs exécutent les tâches de blocage.

Comment Waitress gère-t-elle les tâches simultanées?

À peu près de la même manière que je viens de décrire ci-dessus. Et pour les travailleurs, cela crée des threads, pas des processus.

comment le python GIL les affecte

Waitress utilise des threads pour les travailleurs. Donc, oui, ils sont affectés par GIL en ce qu'ils ne sont pas vraiment simultanés bien qu'ils semblent l'être. "Asynchrone" est le terme correct.

Threads in Python s'exécute à l'intérieur d'un seul processus, sur un seul cœur de processeur, et ne s'exécute pas en parallèle. Un thread acquiert le GIL pendant un très petit laps de temps et exécute son code, puis le GIL est acquis par un autre fil.

Mais comme le GIL est libéré sur les E/S réseau, le processus parent acquerra toujours le GIL chaque fois qu'il y a un événement réseau (comme une demande entrante) et de cette façon, vous pouvez rester assuré que le GIL n'affectera pas les opérations liées au réseau ( comme recevoir des demandes ou envoyer une réponse).

D'un autre côté, Python sont en fait simultanés: ils peuvent s'exécuter en parallèle sur plusieurs cœurs. Mais Waitress n'utilise pas de processus.

Devez-vous vous inquiéter?

Si vous ne faites que de petites tâches de blocage telles que la lecture/écriture de bases de données et que vous ne desservez que quelques centaines d'utilisateurs par seconde, alors utiliser des threads n'est pas si mal.

Pour servir un grand nombre d'utilisateurs ou effectuer des tâches de blocage de longue durée, vous pouvez envisager d'utiliser des files d'attente de tâches externes telles que Celery . Ce sera bien mieux que de générer et de gérer vous-même les processus.

2
xyres