2011-08-22 69 views
0

我所做的是一個電影網站。它會顯示最新的電影信息和放映時間。
我有一個cron作業來更新所有播放的電影。但是,每當它運行時,它都會拋出一個ApiProxy $ CancelledException,並且具有大約4706364 cpu_ms 4644739 api_cpu_ms的可怕cpu時間,這會使我的APP很快超過配額。有人能幫助我嗎?謝謝!!

播放電影的數量大約是25,和場次的數量約爲650

我的代碼

// Get all the playing movies from the datasotre 
Query query = pm.newQuery(Movie.class); 
query.setFilter("playing == true"); 
List<Movie> playingMovies = (List<Movie>) query.execute(); 

// Update every playing movie 
for (Movie m : playingMovies) { 
    // getMovie() will return a movie with latest movie info and showtimes 
    Movie leMovie = getMovie(m.getId()); 
    leMovie.setKey(m.getKey()); 
    leMovie.setFans(m.getFans()); 
    // because leMovie has the latest showtimes so I need to delete the older showtimes 
    m.getShowtimeList().clear(); 

    pm.makePersistent(leMovie); 
} 

我的電影類

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class Movie { 


    @Persistent 
    private Set<Key> fans; 

    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Key key; 

    @Persistent 
    private String id; 

    @Persistent 
    private boolean playing; 

    @Persistent 
    private int gate; 

    @Persistent 
    private String picUrl; 

    @Persistent 
    private String mainName; 

    @Persistent(mappedBy = "movie") 
    @Element(dependent = "true") 
    private List<Showtime> showtimeList; 

    //...... 

的例外

2011-08-22 10:30:00.138 
/cron/update-movie 
com.google.apphosting.api.ApiProxy$CancelledException: The API call datastore_v3.Put() was explicitly cancelled. 
    at com.google.apphosting.runtime.ApiProxyImpl$5.get(ApiProxyImpl.java:298) 
    at com.google.apphosting.runtime.ApiProxyImpl$5.get(ApiProxyImpl.java:296) 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67) 
    at com.google.appengine.api.datastore.FutureHelper$CumulativeAggregateFuture.get(FutureHelper.java:144) 
    at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:72) 
    at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:33) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl$2.runInternal(DatastoreServiceImpl.java:113) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl$2.runInternal(DatastoreServiceImpl.java:110) 
    at com.google.appengine.api.datastore.TransactionRunner.runInTransaction(TransactionRunner.java:31) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:110) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:94) 
    at org.datanucleus.store.appengine.RuntimeExceptionWrappingDatastoreService.put(RuntimeExceptionWrappingDatastoreService.java:94) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:180) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:139) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:134) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.updateObject(DatastorePersistenceHandler.java:536) 
    at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4576) 
    at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2814) 
    at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2754) 
    at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2893) 
    at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:369) 
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:256) 
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:801) 
    at org.datanucleus.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:271) 
    at com.mm.servlet.UpdateMovieServlet.doGet(UpdateMovieServlet.java:100) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:249) 
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
    at org.mortbay.jetty.Server.handle(Server.java:326) 
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) 
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) 
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) 
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) 
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135) 
    at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:262) 
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$2.handleRequest(RuntimePb.java:9819) 
    at com.google.net.rpc.impl.RpcUtil.handleRequest(RpcUtil.java:445) 
    at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:414) 
    at com.google.net.rpc.impl.Server$RpcTask.runInContext(Server.java:579) 
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:454) 
    at com.google.tracing.TraceContext.runInContext(TraceContext.java:694) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:332) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:324) 
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:452) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:636) 
C 2011-08-22 10:30:00.144 
Uncaught exception from servlet 
com.google.apphosting.api.ApiProxy$CancelledException: The API call datastore_v3.Put() was explicitly cancelled. 
    at com.google.apphosting.runtime.ApiProxyImpl$5.get(ApiProxyImpl.java:298) 
    at com.google.apphosting.runtime.ApiProxyImpl$5.get(ApiProxyImpl.java:296) 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67) 
    at com.google.appengine.api.datastore.FutureHelper$CumulativeAggregateFuture.get(FutureHelper.java:144) 
    at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:72) 
    at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:33) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl$2.runInternal(DatastoreServiceImpl.java:113) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl$2.runInternal(DatastoreServiceImpl.java:110) 
    at com.google.appengine.api.datastore.TransactionRunner.runInTransaction(TransactionRunner.java:31) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:110) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl.put(DatastoreServiceImpl.java:94) 
    at org.datanucleus.store.appengine.RuntimeExceptionWrappingDatastoreService.put(RuntimeExceptionWrappingDatastoreService.java:94) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:180) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:139) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.put(DatastorePersistenceHandler.java:134) 
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.updateObject(DatastorePersistenceHandler.java:536) 
    at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4576) 
    at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2814) 
    at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2754) 
    at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2893) 
    at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:369) 
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:256) 
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:801) 
    at org.datanucleus.jdo.JDOPersistenceManager.close(JDOPersistenceManager.java:271) 
    at com.mm.servlet.UpdateMovieServlet.doGet(UpdateMovieServlet.java:100) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:249) 
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
    at org.mortbay.jetty.Server.handle(Server.java:326) 
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) 
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) 
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) 
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) 
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135) 
    at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:262) 
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$2.handleRequest(RuntimePb.java:9819) 
    at com.google.net.rpc.impl.RpcUtil.handleRequest(RpcUtil.java:445) 
    at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:414) 
    at com.google.net.rpc.impl.Server$RpcTask.runInContext(Server.java:579) 
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:454) 
    at com.google.tracing.TraceContext.runInContext(TraceContext.java:694) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:332) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:324) 
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:452) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:636) 
W 2011-08-22 10:30:00.451 
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) 

回答

1

也許答覆已經太遲了......

通常的請求時間約爲一分鐘,如果「getMovie(m.getId());」從其他服務器獲取請求信息可能需要很長時間,並經過一分鐘。

GAE任務有更多時間來運行作業,所以更好地使用cron來排隊一項新任務,並讓appengine在後臺執行您的工作。

Task t = new Task(); 
      t.setUrl(URL_SERVLET_TO_UPDATE_MOVIES); 

      //submit task 
      TaskReference tr = queue.add(t); 

這個servlet運行更新電影的工作。如果你需要更多的時間(假設你有足夠多的電影),每個查詢你只能得到幾個電影,實現它們,獲得一個Cursor(作爲範圍),並使用該光標排入一個新的任務:參數傳遞給servlet。 這個新任務將從下一部電影開始實施(感謝光標),您將有充分的時間完成您的工作。你可以連鎖任務直到你的工作完成。

在你的servlet找光標爲PARAM:

String encodedCursor = req.getParameter(CURSOR_PARAM); 
     if ( encodedCursor != null){ 
      oldCursor = Cursor.fromWebSafeString(encodedCursor); 
     } 

您可以使用此光標從你查詢的最後一部電影來查詢。 從新查詢中獲取新遊標並將其作爲參數添加到新任務。

Task t = new Task(); 
      t.setUrl(PROCESSOR_SERVLET); 

      //add cursor as parameter 
      t.addParameter(CURSOR_PARAM, cursor.toWebSafeString()); 

      //submit task 
      TaskReference tr = queue.add(t); 

使用任務和光標,您將在避免時間限制的背景下完成您的工作。 當然,也有配額那邊......

文件有關遊標: https://developers.google.com/appengine/docs/java/datastore/queries#Query_Cursors

+0

或者使用後端。 – Mayumi