处理HardDeadlineExceededError的任务策略

Ste*_*vko 7 java google-app-engine servlets scheduled-tasks

我有许多任务/ servlet正在击中HardDeadlineExceededError,这使得一切都处于"仍处于执行"状态.

正在完成的工作很容易超过29秒的阈值.

我尝试捕获DeadlineExceededException并基于Exception以保存退出状态,但这些异常处理程序都没有被捕获...

有没有办法确定哪些任务在队列中或当前正在执行?

有没有其他策略来处理这种情况?

我正在处理的情况记录在"请求计时器"标题下.

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

    }
}
Run Code Online (Sandbox Code Playgroud)

当我遇到这种情况时,这是日志文件条目......看来我的数据库事务花费的时间太长了.

  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)
Run Code Online (Sandbox Code Playgroud)

Mar*_*arc 3

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

如果 HDEE 发生在您自己的代码中,则可以在没有 DEE 的情况下抛出 HDEE。
通常最耗时的事情是等待 API 调用返回
,因此此处超时将导致 API 调用因
DEE 而停止。所以如果你不经常调用API,你可以直接点击HDEE。

我还有长时间运行的任务,这些任务会迭代数据处理
和存储结果。我使用的迭代器会
在 20 秒后停止返回结果并保存最后处理的对象,然后启动
新任务以继续处理。

我原来的解决方案捕获了 DEE,然后进行了清理,但这
不再可靠地工作。