2010-05-30 8 views
7

Tengo un número de tareas/servlets que están golpeando el HardDeadlineExceededError que deja todo pendiente en un estado 'todavía ejecutándose'.estrategias de tareas para manejar HardDeadlineExceededError

El trabajo que se realiza puede exceder fácilmente el umbral de 29 segundos.

trato de coger el DeadlineExceededException y la base de excepciones con el fin de guardar el estado de salida pero ninguno de estos controladores de excepciones se están detectando ...

¿Hay una manera de determinar cuáles son las tareas en la cola o actualmente en ejecución?

¿Existen otras estrategias para hacer frente a esta situación?

La situación con la que estoy tratando está documentada en el encabezado "The Request Timer".

// task handler for retrieving information from external web services 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException { 

    String taskRetryCountParam = req.getParameter("X-AppEngine-TaskRetryCount"); 
    int taskRetryCount = (taskRetryCountParam==null) ? 0 : Integer.parseInt(taskRetryCountParam); 
      // look up the persistent 'task' and mark it as 'running' 

    logger.info(this.getClass().getName() + ".doPost("+ taskId + ") retryCount=" + taskRestryCount); 


    // Do lots of heavy lifting here 
    // like calling external web services using URL fetch service 
      // and saving the contents into our database. 

      // look up the persistent 'task' and mark it as 'completed' 

    } catch (DeadlineExceededException deadline) { 
     // got this deadline exception 
        // look up the persistent 'task' and mark it as 'errored - try again' 
     logger.warning("DeadlineExceeded Exception while loading content " + deadline.getMessage()); 
     resp.setStatus(HttpServletResponse.SC_REQUEST_TIMEOUT); 

     } 
    } catch (Exception unknown) { 
     // got some unknown exception 
        // look up the persistent 'task' and mark it as 'errored - cancelled' 
     logger.severe("General Exception while loading content exception:" + unknown.getMessage()); 
     resp.setStatus(HttpServletResponse.SC_OK); 

    } 
} 

Aquí es las entradas del archivo de registro cuando me meto en esta situación ... Parece que mis transacciones de bases de datos están tomando demasiado tiempo, cuando llega el momento de.

W 05-30 12:42PM 09.535 
    Error for /loadstatus 
    com.google.apphosting.runtime.HardDeadlineExceededError: This request (083793d1091c2ca3) started at 2010/05/30 19:41:39.814 UTC and was still executing at 2010/05/30 19:42:09.529 UTC. 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:443) 
    at java.util.concurrent.TimeUnit.timedWait(Unknown Source) 
    at com.google.apphosting.runtime.AsyncFuture.get(AsyncFuture.java:60) 
    at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.get(ApiProxyImpl.java:326) 
    at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.get(ApiProxyImpl.java:217) 
    at com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:131) 
    at com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:43) 
    at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:104) 
    at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:102) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:102) 
    at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:43) 
    at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98) 
    at com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall(DatastoreApiHelper.java:58) 
    at com.google.appengine.api.datastore.TransactionImpl.makeSyncCall(TransactionImpl.java:42) 
    at com.google.appengine.api.datastore.TransactionImpl.makeSyncCall(TransactionImpl.java:56) 
    at com.google.appengine.api.datastore.TransactionImpl.commit(TransactionImpl.java:66) 
    at org.datanucleus.store.appengine.DatastoreTransaction.commit(DatastoreTransaction.java:61) 
    at org.datanucleus.store.appengine.DatastoreXAResource.commit(DatastoreXAResource.java:88) 
    at org.datanucleus.transaction.Transaction.commit(Transaction.java:149) 
    at org.datanucleus.transaction.TransactionManager.commit(TransactionManager.java:95) 
    at org.datanucleus.TransactionImpl.internalCommit(TransactionImpl.java:390) 
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:258) 
    at org.datanucleus.jdo.JDOTransaction.commit(JDOTransaction.java:83) 
    at org.datanucleus.store.appengine.jdo.DatastoreJDOTransaction.commit(DatastoreJDOTransaction.java:56) 
    <snip> 
    C 05-30 12:42PM 09.629 
    Uncaught exception from servlet 
    com.google.apphosting.runtime.HardDeadlineExceededError: This request (083793d1091c2ca3) started at 2010/05/30 19:41:39.814 UTC and was still executing at 2010/05/30 19:42:09.529 UTC. 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:443) 
    at java.util.concurrent.TimeUnit.timedWait(Unknown Source) 
    at com.google.apphosting.runtime.AsyncFuture.get(AsyncFuture.java:60) 
    at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.get(ApiProxyImpl.java:326) 
    at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.get(ApiProxyImpl.java:217) 
    at com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:131) 
    at com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:43) 
    at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:104) 
    at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:102) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:102) 
    at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:43) 
    at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98) 
    at com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall(DatastoreApiHelper.java:58) 
    at com.google.appengine.api.datastore.TransactionImpl.makeSyncCall(TransactionImpl.java:42) 
    at com.google.appengine.api.datastore.TransactionImpl.makeSyncCall(TransactionImpl.java:56) 
    at com.google.appengine.api.datastore.TransactionImpl.commit(TransactionImpl.java:66) 
    at org.datanucleus.store.appengine.DatastoreTransaction.commit(DatastoreTransaction.java:61) 
    at org.datanucleus.store.appengine.DatastoreXAResource.commit(DatastoreXAResource.java:88) 
    at org.datanucleus.transaction.Transaction.commit(Transaction.java:149) 
    at org.datanucleus.transaction.TransactionManager.commit(TransactionManager.java:95) 
    at org.datanucleus.TransactionImpl.internalCommit(TransactionImpl.java:390) 
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:258) 
    at org.datanucleus.jdo.JDOTransaction.commit(JDOTransaction.java:83) 
    at org.datanucleus.store.appengine.jdo.DatastoreJDOTransaction.commit(DatastoreJDOTransaction.java:56) 
    <snip> 
    W 05-30 12:42PM 09.644 
    A serious problem was encountered with the process that handled this request, causing it to exit. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may be throwing exceptions during the initialization of your application. (Error code 104) 
+2

Debería poder ver [DeadlineExceededException] (http://code.google.com/appengine/docs/java/runtime.html#The_Request_Timer). ¿Puedes publicar algo de tu código? –

+0

@Matthew: No hago GAE, pero 'HardDeadlineExceededError' no suena como una' Excepción'. – BalusC

+0

@Balus, no dije que fuera. 'DeadlineExceededException' y' HardDeadlineExceededError' son dos cosas diferentes. El primero puede ser atrapado. El último no puede, y se lanza si lleva más de un segundo procesar el primero. –

Respuesta

3

http://groups.google.com/group/google-appengine-java/msg/e3fd2b621bb96013

HDEEs pueden ser lanzadas sin DEE si sucede en su propio código.
Por lo general, la mayor parte del tiempo que consume está esperando llamadas a API para
de retorno por lo que un tiempo de espera de aquí dará lugar a la llamada a la API parar con una DEE
. Entonces, si no llamas a la API a menudo, puedes presionar HDEE directamente.

También tengo tareas de larga ejecución que se repiten a través del procesamiento de datos
y el almacenamiento de resultados. Uso un iterador que deja de devolver resultados
después de 20 segundos y guarda el último objeto procesado y luego inicia
de una nueva tarea para continuar el procesamiento.

Mi solución original capturó el DEE y luego se limpió, pero
dejó de funcionar de manera confiable.

+0

Gracias por la entrada Marc. ¿Capturas un error e inferir HDEE de él o de algo más? – Stevko

+1

No se puede detectar el error HDEE. No porque no puedas agregar tal captura (puedes), sino que tu código se detiene. Para esto, estaba el DEE, que debería lanzarse medio segundo antes del HDEE, pero esto no funciona si estás dentro de tu propio código. – Marc

Cuestiones relacionadas