Question

Je les téléchargements du site de traitement du module de téléchargement nginx, mais ont encore besoin de transférer des fichiers (disons chaque 3-20mb) à nos cdn, et déléguerait plutôt pas à un travail de fond.

Quelle est la meilleure façon de le faire avec une tornade sans bloquer les autres demandes? Puis-je faire cela dans un rappel async?

Était-ce utile?

La solution 2

conseils sur les points de groupe google tornade à l'aide d'un rappel async (documenté http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests ) pour déplacer le fichier vers le cdn.

le module de téléchargement nginx écrit le fichier sur le disque et passe ensuite les paramètres décrivant le téléchargement (s) retour à la vue. Par conséquent, le fichier est pas en mémoire, mais le temps qu'il faut pour lire

de disque qui provoqueraient le processus de demande de se bloquer, mais pas d'autres processus de tornade, afaik-est négligeable.

Cela dit, tout ce qui ne fonctionne pas besoin à traiter ne devrait pas être en ligne, et devrait être reporté à une file d'attente de tâches comme celeryd ou similaire.

Autres conseils

Vous trouverez peut-être utile dans l'architecture globale de votre site pour ajouter un service de file d'attente message tel que RabbitMQ .

Cela vous permettra de compléter le téléchargement via le module nginx, puis dans le gestionnaire de tornade, envoyer un message contenant le chemin du fichier téléchargé et sortie. Un processus distinct regarderaient pour ces messages et gérer le transfert à votre CDN. Ce type de service serait utile pour de nombreuses autres tâches qui pourraient être traitées hors ligne (envoi de courriels, etc ..). À mesure que votre système se développe, cela vous donne également un mécanisme à l'échelle en déplaçant le traitement des files d'attente à des machines séparées.

J'utilise une architecture très similaire à ce sujet. Assurez-vous d'ajouter votre message processus de consommation supervisord ou tout ce que vous utilisez pour gérer vos processus.

En ce qui concerne la mise en œuvre, si vous êtes sur Ubuntu installation RabbitMQ est simple:

sudo apt-get install rabbitmq-server

Sur CentOS w / dépôts EPEL:

yum install rabbit-server

Il y a un certain nombre de liaisons Python à RabbitMQ. Pika est l'un d'entre eux et il arrive à créer par un de href="http://www.lshift.net/" rel="noreferrer"> LShift , qui est responsable de RabbitMQ .

Voici un peu de code échantillon rel="noreferrer"> du Pika repo. Vous pouvez facilement imaginer comment la méthode handle_delivery accepterait un message contenant un filepath et le pousser à votre CDN.

import sys
import pika
import asyncore

conn = pika.AsyncoreConnection(pika.ConnectionParameters(
        sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1',
        credentials = pika.PlainCredentials('guest', 'guest')))

print 'Connected to %r' % (conn.server_properties,)

ch = conn.channel()
ch.queue_declare(queue="test", durable=True, exclusive=False, auto_delete=False)

should_quit = False

def handle_delivery(ch, method, header, body):
    print "method=%r" % (method,)
    print "header=%r" % (header,)
    print "  body=%r" % (body,)
    ch.basic_ack(delivery_tag = method.delivery_tag)

    global should_quit
    should_quit = True

tag = ch.basic_consume(handle_delivery, queue = 'test')
while conn.is_alive() and not should_quit:
    asyncore.loop(count = 1)
if conn.is_alive():
    ch.basic_cancel(tag)
    conn.close()

print conn.connection_close
scroll top