¿Cómo se implementa DeadlineExceededException en Google App Engine para Java?

Las aplicaciones en Google App Engine deben tener solicitudes web que devuelvan datos de respuesta dentro de los 30 segundos. Cuando se excede este tiempo, se lanza una excepción DeadlineExceededException :

 /time.jsp java.lang.ClassCastException: com.google.apphosting.api.DeadlineExceededException cannot be cast to javax.servlet.ServletException at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:754) at org.apache.jsp.time_jsp._jspService(time_jsp.java:66) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94) at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at org.mortbay.jetty.Server.handle(Server.java:313) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830) at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:125) at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4755) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4753) at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24) at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359) at com.google.net.rpc.impl.Server$2.run(Server.java:800) at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56) at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:510) at com.google.net.rpc.impl.Server.startRpc(Server.java:756) at com.google.net.rpc.impl.Server.processRequest(Server.java:348) at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:459) at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319) at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290) at com.google.net.async.Connection.handleReadEvent(Connection.java:419) at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:762) at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207) at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101) at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251) at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:373) at java.lang.Thread.run(Unknown Source) 

Como se hace ¿Tienes algún código fuente abierto?

El temporizador de solicitud

Un manejador de solicitudes tiene un tiempo limitado para generar y devolver una respuesta a una solicitud, generalmente alrededor de 30 segundos. Una vez que se ha alcanzado el plazo, el gestor de solicitudes se interrumpe.

El entorno de ejecución de Java interrumpe el servlet lanzando una com.google.apphosting.api.DeadlineExceededException. Si el manejador de solicitudes no detecta esta excepción, como ocurre con todas las excepciones no detectadas, el entorno de ejecución devolverá un error de servidor HTTP 500 al cliente.

El manejador de solicitudes puede detectar este error para personalizar la respuesta. El entorno de ejecución le da al manejador de solicitudes un poco más de tiempo (menos de un segundo) después de generar la excepción para preparar una respuesta personalizada.

Si bien una solicitud puede tardar hasta 30 segundos en responder, App Engine está optimizado para aplicaciones con solicitudes de corta duración, generalmente aquellas que toman unos pocos cientos de milisegundos. Una aplicación eficiente responde rápidamente para la mayoría de las solicitudes. Una aplicación que no se adapte bien a la infraestructura de App Engine.

Parte del tiempo de ejecución == No usar hilos. Esta característica es una modificación de la máquina virtual, y no me quedaría sin aliento esperando el código fuente.

Supongo que el mecanismo detrás de esta excepción se implementa en la infraestructura del motor de aplicaciones, que no es de código abierto.

Sin embargo, puede usar esta función para redes o, más generalmente, cualquier código de E / S limitado usando java.nio (por ejemplo, Selector ). En su lugar, para el código delimitado por la CPU puede usar java.util.concurrent (por ejemplo, Futuro ).

Esto se puede hacer de la siguiente manera, use IO sin locking , y cree un hilo de vigilancia que registre la hora de inicio y arroje la excepción cuando haya transcurrido el tiempo transcurrido. El tutorial de IO sin locking muestra cómo se puede hacer esto con el ejemplo Ping.java .

Puede ser una respuesta muy tardía, pero útil para nuevos alumnos.

 @Override protected final void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException { res.setContentType("text/html"); final PrintWriter out = res.getWriter(); final String a = req.getParameter("a"); try { for (int i = 0; 1 < 5; i++) { out.print("Mode " + a + " Running " + i + " " + MainServlon.doubleIt(i)); Thread.sleep(90000); } } catch (final InterruptedException e) { e.printStackTrace(); } catch (final DeadlineExceededException e) { out.print("Train is going to stop. Let me close this story for now!"); } }