我所做的是电影网站。它将显示最新的电影信息和放映时间 我有一个cron工作来更新所有播放的电影。但是,每当它运行时,它会抛出一个ApiProxy $ CancelledException并且有一个可怕的cpu-time,大约4706364 cpu_ms 4644739 api_cpu_ms,这使我的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)
答案 0 :(得分: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运行更新电影的工作。
即使需要更多时间(假设你有足够的电影),每次查询只能获得少量电影,实现它们,获得光标(作为范围)并将该光标作为参数排入新任务到servlet。 这个新任务将从你必须实现的下一部电影开始(感谢光标),你将有足够的时间来完成你的工作。你可以把任务链起来直到你的工作完成。
在你的servlet中寻找一个光标作为参数:
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