urls template ifequal examples django asynchronous mod-wsgi

template - Django tareas asincrónicas de larga ejecución con hilos/procesamiento



django views (3)

Descubrí que el uso de Decoradores uWSGI es bastante más simple que usar Apio si solo necesitas ejecutar una larga tarea en segundo plano. Piensa que Apio es la mejor solución para proyectos pesados ​​serios, y es sobrecarga para hacer algo simple.

Para empezar a usar decoradores uWSGI solo necesita actualizar su configuración uWSGI con

<spooler-processes>1</spooler-processes> <spooler>/here/the/path/to/dir</spooler>

escribir código como:

@spoolraw def long_task(arguments): try: doing something with arguments[''myarg'']) except Exception as e: ...something... return uwsgi.SPOOL_OK def myView(request) long_task.spool({''myarg'': str(someVar)}) return render_to_response(''done.html'')

Entonces, cuando comienza la vista en uWSGI, aparece el registro:

[spooler] written 208 bytes to file /here/the/path/to/dir/uwsgi_spoolfile_on_hostname_31139_2_0_1359694428_441414

y cuando terminó la tarea:

[spooler /here/the/path/to/dir pid: 31138] done with task uwsgi_spoolfile_on_hostname_31139_2_0_1359694428_441414 after 78 seconds

Hay restricciones extrañas (para mí):

- spool can receive as argument only dictionary of strings, look like because it''s serialize in file as strings. - spool should be created on start up so "spooled" code it should be contained in separate file which should be defined in uWSGI config as <import>pyFileWithSpooledCode</import>

Descargo de responsabilidad : sí sé que hay varias preguntas similares en SO. Creo que he leído la mayoría si no todos, pero no encontré una respuesta a mi pregunta real (ver más adelante). También sé que el uso de apio u otros sistemas de colas asíncronas es la mejor manera de lograr tareas de larga ejecución o, al menos, utilizar una secuencia de comandos administrada por cron. También hay documentos mod_wsgi sobre procesos e hilos, pero no estoy seguro de que todo esté correcto.

La pregunta es:

¿Cuáles son los riesgos / problemas exactos involucrados con el uso de las soluciones enumeradas allí? ¿Alguno de ellos es viable para tareas de larga duración (vale, a pesar de que el apio es más adecuado)? Mi pregunta es realmente más acerca de comprender los aspectos internos de wsgi y python / django que encontrar la mejor solución general. Problemas con el bloqueo de hilos, acceso inseguro a variables, procesamiento de zombies, etc.

Digamos:

  1. mi "long_process" está haciendo algo realmente seguro. incluso si falla, no me importa.
  2. python> = 2.6
  3. Estoy usando mod_wsgi con apache (¿cambiará algo con uwsgi o gunicorn?) En modo daemon

mod_wsgi conf:

WSGIDaemonProcess NAME user=www-data group=www-data threads=25 WSGIScriptAlias / /path/to/wsgi.py WSGIProcessGroup %{ENV:VHOST}

Pensé que estas son las opciones disponibles para iniciar procesos separados (en un sentido amplio) para llevar a cabo una tarea de larga ejecución mientras se responde rápidamente al usuario:

os.fork

import os if os.fork()==0: long_process() else: return HttpResponse()

subproceso

import subprocess p = subprocess.Popen([sys.executable, ''/path/to/script.py''], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

(donde es probable que el script sea un comando manage.py)

trapos

import threading t = threading.Thread(target=long_process, args=args, kwargs=kwargs) t.setDaemon(True) t.start() return HttpResponse()

NÓTESE BIEN.

Debido al bloqueo de intérprete global, en CPython solo un hilo puede ejecutar el código de Python a la vez (aunque ciertas bibliotecas orientadas al rendimiento podrían superar esta limitación). Si desea que su aplicación aproveche al máximo los recursos computacionales de las máquinas multi-core, se le recomienda usar multiprocesamiento. Sin embargo, el enhebrado sigue siendo un modelo apropiado si desea ejecutar múltiples tareas vinculadas a E / S simultáneamente.

El hilo principal volverá rápidamente (la httpresponse). ¿El hilo largo engendrado bloqueará a wsgi de hacer otra cosa por otra petición?

multiproceso

from multiprocessing import Process p = Process(target=_bulk_action,args=(action,objs)) p.start() return HttpResponse()

Esto debería resolver el problema de concurrencia del hilo, ¿no es así?

Entonces esas son las opciones que podría pensar. ¿Qué funcionaría y qué no, y por qué?


Para la pregunta:

¿El hilo largo engendrado bloqueará a wsgi de hacer otra cosa por otra petición?

la respuesta es no.

Sin embargo, debe tener cuidado al crear subprocesos de fondo a partir de una solicitud en caso de que simplemente cree un gran número de ellos y obstruya todo el proceso. Realmente necesita un sistema de cola de tareas incluso si está haciendo cosas en proceso.

Con respecto a hacer un fork o un ejecutivo de un proceso web, especialmente de Apache, eso generalmente no es una buena idea ya que Apache puede imponer condiciones extrañas en el entorno del subproceso creado que podría interferir técnicamente con su funcionamiento.

El uso de un sistema como Apio todavía es probablemente la mejor solución.


os.fork

Un tenedor clonará el proceso principal, que en este caso es tu pila Django. Ya que simplemente desea ejecutar un script de Python por separado, esto parece una cantidad innecesaria de hinchazón.

subproceso

Se espera que el uso del subprocess sea ​​interactivo. En otras palabras, si bien puede usar esto para generar efectivamente un proceso, se espera que en algún momento lo termine cuando termine. Es posible que Python lo solucione si deja uno en ejecución, pero supongo que esto provocará una pérdida de memoria.

trapos

Los hilos son unidades definidas de lógica. Comienzan cuando se llama a su método run() y finalizan cuando termina la run() método run() . Esto los hace muy adecuados para crear una rama de la lógica que se ejecutará fuera del alcance actual. Sin embargo, como mencionó, están sujetos al bloqueo de intérprete global.

multiproceso

Esto es básicamente hilos de esteroides. Tiene los beneficios de un hilo, pero no está sujeto a Global Interpreter Lock, y puede aprovechar las arquitecturas multi-core. Sin embargo, es más complicado trabajar con ellos como resultado.

Entonces, tus elecciones realmente se reducen a hilos o multiprocesamiento. Si puede cumplir con un hilo y tiene sentido para su aplicación, vaya con un hilo. De lo contrario, use multiprocesamiento.