2012-02-29 15 views
6

Estoy desarrollando un servidor web django en el que otra máquina (con una dirección IP conocida) puede cargar una hoja de cálculo en mi servidor web. Después de la hoja de cálculo se ha actualizado, quiero activar algún procesamiento/validación/análisis en la hoja de cálculo (que puede tomar más de 5 minutos --- demasiado tiempo para que el otro servidor espere razonablemente una respuesta) y luego enviar el otro máquina (con una IP conocida) una respuesta Http que indica que el procesamiento de datos ha finalizado.activar la función después de devolver HttpResponse desde la vista de django

que darse cuenta de que no se puede hacer processing.data() después de regresar de una HttpResponse, pero funcionalmente quiero código que se ve algo como esto:

# processing.py 
def spreadsheet(*args, **kwargs): 
    print "[robot voice] processing spreadsheet........." 
    views.finished_processing_spreadsheet() 

# views.py 
def upload_spreadsheet(request): 
    print "save the spreadsheet somewhere" 
    return HttpResponse("started processing spreadsheet") 
    processing.data() 

def finished_processing_spreadsheet(): 
    print "send good news to other server (with known IP)" 

Yo sé cómo escribir cada función individual, pero ¿cómo puedo efectivamente llamar processing.data()después deviews.upload_spreadsheet ha devuelto una respuesta?

Intenté usar django's request_finished signaling framework pero esto no desencadena el método processing.spreadsheet() después de devolver el HttpResponse. Intenté usar un decorador en views.upload_spreadsheet con el mismo problema.

Tengo una idea de que esto podría tener algo que ver con escribir middleware o posiblemente un custom class-based view, ninguno de los cuales tengo alguna experiencia, así que pensé que plantearía la pregunta al universo en busca de alguna ayuda.

Gracias por su ayuda!

Respuesta

4

De hecho, Django tiene un modelo sincrónico. Si desea hacer un procesamiento asincrónico real, necesita una cola de mensajes. El más utilizado con django es el apio, puede parecer un poco "exagerado", pero es una buena respuesta.

¿Por qué necesitamos esto? porque en una aplicación wsgi, apache da la solicitud al ejecutable y el ejecutable devuelve texto. Es solo una vez cuando el ejecutable termina su ejecución que apache conoce el final de la solicitud.

+0

Gracias por explicar por qué es necesario, Cristophe. De acuerdo con la explicación tuya y jpic, creo que revisaré el apio después de dormir un poco más. – dino

3

El problema con su implementación es que si el número de hojas de cálculo en proceso es igual al número de trabajadores: su sitio web ya no responderá.

se debe utilizar una cola de tareas fondo, básicamente tiene 2 procesos: su servidor y un administrador de tareas de fondo. El servidor debe delegar el procesamiento de la hoja de cálculo al gestor de tareas en segundo plano. Cuando la tarea de fondo está lista, debe informar al servidor de alguna manera. Por ejemplo, puede hacer model_with_spreadsheet.processed = datetime.datetime.now().

Debe utilizar un gestor de fondo trabajo como django-ztask (configuración muy fácil), celery (muy potente, algo excesivo en su caso) o incluso uwsgi spooler (que obviamente requiere el despliegue uwsgi).

+0

Gracias por la respuesta rápida. De acuerdo con las respuestas de ti y christophe31, creo que revisaré el apio después de dormir un poco más. – dino

+0

cierre la pregunta por favor – jpic

Cuestiones relacionadas