2011-01-22 45 views
5

¿Hay alguna manera de manejar cualquier fecha límite al ejecutar una tarea? El DeadlineExceededError se lanza después de 10 minutos de ejecución y me dan unos segundos después de eso para hacer algunas cosas. Quiero limpiar algunas cosas antes de que la tarea se muera y crear una nueva tarea. Esto puede tomar algunos segundos. ¿Hay alguna forma de hacerlo capturando cualquier excepción, como alrededor de 9 minutos? Sé que puedo lanzar manualmente una excepción después de 9 minutos. ¿Pero puede esto hacerse automáticamente por GAE?Google App Engine Task Deadline

class FillMtxHandler(): 

def post(self,index,user,seqlen): 

    try :   
     FillMtx(index,user,seqlen) 

    except DeadlineExceededError: 

     deferred.defer(self.post,index,user,seqlen) 

El de arriba es mi código. index es una lista y comienza desde 0. Se incrementará dentro de FillMtx. Una vez que se ha superado el plazo de error, deseo continuar desde donde se aumentó el último índice. Obtengo el siguiente error

The API call taskqueue.BulkAdd() was explicitly cancelled. 
Traceback (most recent call last): 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 517, in __call__ 
    handler.post(*groups) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", line 258, in post 
    run(self.request.body) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", line 124, in run 
    return func(*args, **kwds) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", line 166, in invoke_member 
    return getattr(obj, membername)(*args, **kwargs) 
    File "/base/data/home/apps/0xxopdp/3.347813391084738922/fillmtx.py", line 204, in post 
    deferred.defer(self.post,index,user,seqlen) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", line 241, in defer 
    return task.add(queue, transactional=transactional) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/taskqueue/taskqueue.py", line 688, in add 
    return Queue(queue_name).add(self, transactional=transactional) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/taskqueue/taskqueue.py", line 744, in add 
    self.__AddTasks(tasks, transactional) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/taskqueue/taskqueue.py", line 770, in __AddTasks 
    apiproxy_stub_map.MakeSyncCall('taskqueue', 'BulkAdd', request, response) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 86, in MakeSyncCall 
    return stubmap.MakeSyncCall(service, call, request, response) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 286, in MakeSyncCall 
    rpc.CheckSuccess() 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_rpc.py", line 126, in CheckSuccess 
    raise self.exception 
CancelledError: The API call taskqueue.BulkAdd() was explicitly cancelled. 

Me parece que se ha creado una nueva tarea y se ha puesto en cola. Pero, ¿por qué GAE arroja este error?

Respuesta

4

No puede controlar cuándo obtiene el error de límite de tiempo excedido. En su lugar, debe usar su propio temporizador (tome la hora del reloj de pared cuando comience, y compárela con la hora actual en cada viaje alrededor de su ciclo principal), y aborte cuando esté lo suficientemente cerca del límite que desea detener.

+0

Gracias por la respuesta. En su publicación sobre diferido, agrega una nueva tarea después de atrapar un DeadlineExceededError. ¿Podemos estar seguros de que la tarea se agregará definitivamente a la cola antes de que se produzca el error de fecha límite? – Sam

+0

@Sam En general, debe agregarse, pero es posible que no lo sea, como ha observado. Si no lo hace, su tarea será puesta en cola (ya que no salió limpiamente); su código puede verificar si ya se hizo el trabajo, y saltar directamente a la fase de limpieza si lo hizo. –

4

No es necesario que presente una excepción después de 9 minutos; cuando se produce la excepción de plazo límite, tiene tiempo suficiente para agregar una tarea de limpieza al Task Queue a través del deferred.

from google.appengine.ext import deferred 
... 
try: 
    # Do your stuff 
except DeadlineExceededError: 
    deferred.defer(do_your_cleanup, ..) 

De esta forma, tiene 10 minutos para hacer las tareas de limpieza que necesita en su aplicación.

+0

¿cómo puedo estar seguro de que la tarea se agregará a la cola de tareas antes de que se llegue al límite estricto? Obtengo el "Error cancelado: la llamada a la API taskqueue.BulkAdd() se canceló explícitamente" aunque se haya agregado la tarea – Sam

+0

Si se agota el tiempo de gracia, el error cancelado entra en acción. – systempuntoout

+0

deferred.defer y taskqueue.add se comportan de la misma manera aquí. En ambos casos, aparece el "Error cancelado" porque el proceso de agregar la tarea a la cola no se completó antes del límite de tiempo difícil. http://code.google.com/appengine/articles/deferred.html ¿cómo puede actualizar el archivo db y crear una tarea antes del período de gracia? – Sam