2010-05-30 13 views
7

Mam wiele zadań/serwletów, które uderzają w HardDeadlineExceededError, pozostawiając wszystko zwisające w stanie "wciąż wykonującym".strategie zadań do obsługi HardDeadlineExceededError

Wykonana praca może z łatwością przekroczyć próg 29 sekund.

próbuję złapać DeadlineExceededException i bazową Exception w celu ratowania stanu wyjście ale żadna z tych procedur obsługi wyjątków są złowionych ...

Czy istnieje sposób, aby określić, które zadania są w kolejce lub aktualnie wykonujesz?

Czy istnieją inne strategie radzenia sobie z tą sytuacją?

Sytuacja, z którą mam do czynienia, jest udokumentowana pod nagłówkiem "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); 

    } 
} 

Oto wpisy pliku dziennika kiedy się do tej sytuacji ... Wydaje się, że moje transakcje są bazy danych trwa zbyt długo, gdy przychodzi czas.

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

Powinieneś być w stanie złapać [DeadlineExceededException] (http://code.google.com/appengine/docs/java/runtime.html#The_Request_Timer). Czy możesz opublikować część swojego kodu? –

+0

@Matthew: Nie robię GAE, ale 'HardDeadlineExceededError' nie brzmi jak być' Exception'. – BalusC

+0

@Balus, nie powiedziałem, że to było. 'DeadlineExceededException' i' HardDeadlineExceededError' to dwie różne rzeczy. Ten pierwszy można złapać. Ten ostatni nie może i jest rzucany, jeśli zajmie ci więcej niż sekundę na przetworzenie tego pierwszego. –

Odpowiedz

3

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

HDEEs może być rzucony bez DEE jeśli to się dzieje w swoim własnym kodzie.
Zazwyczaj najbardziej czasochłonna rzecz oczekuje na wywołania API do
return, więc limit czasu w tym miejscu spowoduje przerwanie połączenia API z
DEE. Więc jeśli często nie wywołujesz interfejsu API, możesz uderzyć bezpośrednio w HDEE.

Mam również długo działające zadania, które są iteracyjne poprzez przetwarzanie danych
i przechowywanie wyników. Używam Iteratora, który przestaje zwracać wyniki po upływie 20 sekund i zapisuje ostatni przetworzony obiekt, a następnie kopie
z nowego zadania, aby kontynuować przetwarzanie.

Moje oryginalne rozwiązanie wykryło błąd DEE, a następnie je wyczyściłem, ale ten
przestał działać niezawodnie.

+0

Dzięki za wkład Marc. Czy łapiesz błąd i wyprowadzasz HDEE z niego lub coś innego? – Stevko

+1

Nie można złapać błędu HDEE. Nie dlatego, że nie możesz dodać takiego haka (możesz), ale twój kod jest zatrzymany. Do tego dochodził DEE, który powinien zostać rzucony około pół sekundy przed HDEE, ale to nie działa, jeśli jesteś w swoim własnym kodzie. – Marc

Powiązane problemy