2011-08-22 67 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