2011-12-29 10 views
7

Necesito manejar un proceso grande (tiempo y consumo de memoria) de forma asincrónica en una aplicación web2py llamada dentro de un método de controlador.Procesos de fondo asíncronos con web2py

Mi caso de uso específico es llamar a un proceso a través de stdlib.subprocess y esperar a que salga sin bloquear el servidor web, pero estoy abierto a métodos alternativos.

  • Los ejemplos prácticos serían un plus.
  • recomendaciones de biblioteca de terceros son bienvenidas.
  • La programación CRON no es obligatoria ni necesaria.

Respuesta

7

Suponiendo que tendrá que iniciar varias instancias de la tarea en segundo plano, posiblemente simultáneas, la solución es una cola de tareas. He oído cosas buenas sobre Aplery y RabbitMQ, si está buscando opciones de terceros, y web2py incluye el sistema it's own task queue que podría ser suficiente para sus necesidades.

Con cualquiera de las herramientas, definirá una función que encapsula la operación que desea que realice el proceso en segundo plano. Luego, traiga a los trabajadores de la cola de tareas en línea. El manual web2py y los foros indican que esto se puede hacer con una declaración @reboot en el sistema cron web2py, que se activa cada vez que se inicia el servidor web. Probablemente haya otras formas de iniciar a los trabajadores si esto no es satisfactorio.

En su controlador insertará una tarea en la cola de tareas, pasando los parámetros necesarios como entradas a la función (la función de fondo no se ejecutará en el mismo entorno que el controlador, por lo que no tendrá acceso la sesión, DB, etc. a menos que pase explícitamente los valores apropiados a la función de tarea).

Ahora, para obtener la salida de la operación en segundo plano para el usuario. Cuando inserta una tarea en la cola de tareas, debe obtener una ID única para la tarea. A continuación, implementaría la lógica del controlador (ya sea algo que espera una llamada AJAX o una página que se actualiza hasta completar la tarea) que llama a la API de la cola de tareas para verificar el estado de la tarea especificada. Si el estado de la tarea es "finalizado", devuelva los datos al usuario. Si no, sigue esperando.

+0

Creo que el programador de tareas integrado era justo lo que estaba buscando. –

1

Esto es más difícil de lo que cabría esperar. Tenga en cuenta las advertencias de interbloqueo en el stdlib.subprocess documentation. Es fácil si no te importa bloquear --- usa Popen.communicate. Para evitar el bloqueo, puede administrar el proceso usando stdlib.subprocess desde un hilo.

Mi forma favorita de tratar los subprocesos es usar Twisted's spawnProcess. Pero no es fácil obtener Twisted para jugar bien con otros frameworks.