2010-05-30 5 views
7

ho un certo numero di compiti/servlet che stanno colpendo il HardDeadlineExceededError che sta lasciando tutto appeso in uno stato 'ancora in esecuzione'.strategie per la gestione di attività HardDeadlineExceededError

Il lavoro svolto può facilmente superare la seconda soglia 29.

cerco di prendere il DeadlineExceededException e la base delle eccezioni al fine di salvare lo stato uscita ma nessuno di questi gestori di eccezioni vengono catturati ...

C'è un modo per determinare quali attività sono in coda o attualmente in esecuzione?

Ci sono altre strategie per affrontare questa situazione?

La situazione ho a che fare è documentata sotto "The Request Timer" rubrica.

// 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); 

    } 
} 

Ecco le voci del file di registro, quando mi trovo in questa situazione ... Sembra che le mie transazioni di database stanno prendendo troppo tempo quando arriva il momento di.

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

Dovresti riuscire a prendere [DeadlineExceededException] (http://code.google.com/appengine/docs/java/runtime.html#The_Request_Timer). Puoi pubblicare parte del tuo codice? –

+0

@ Matteo: non faccio GAE, ma 'HardDeadlineExceededError' non suona come essere un' Exception'. – BalusC

+0

@Balus, non ho detto che fosse. 'DeadlineExceededException' e' HardDeadlineExceededError' sono due cose diverse. Il primo può essere catturato. Quest'ultimo non può, e viene lanciato se si impiega più di un secondo per elaborare il primo. –

risposta

3

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

HDEEs possono essere gettati senza un DEE se succede nel proprio codice.
Di solito la maggior parte del tempo cosa che consumano è in attesa di chiamate API al
ritorno in modo un timeout qui comporterà la chiamata API arresto con un DEE
. Quindi, se non chiami spesso l'API, puoi colpire direttamente l'HDEE.

Ho anche attività a lunga esecuzione che eseguono l'iterazione dei dati
e memorizzano i risultati. Io uso un Iterator che smette di restituire i risultati
dopo 20 secondi e salva l'ultimo oggetto elaborato e quindi dà il calcio a
da una nuova attività per continuare l'elaborazione.

La mia soluzione originale ha rilevato il DEE e quindi ripulito ma questo
ha smesso di funzionare in modo affidabile.

+0

Grazie per l'input Marc. Stai rilevando errori e inferendo HDEE da esso o qualcos'altro? – Stevko

+1

Non è possibile rilevare l'errore HDEE. Non perché non è possibile aggiungere una tale presa (è possibile), ma il codice viene interrotto. Per questo, c'era il DEE, che dovrebbe essere lanciato circa mezzo secondo prima dell'HDEE, ma questo non funziona se ci si trova all'interno del proprio codice. – Marc