2009-06-17 10 views
7

Las aplicaciones en Google App Engine deben tener solicitudes web que devuelvan datos de respuesta en 30 segundos. Cuando se supera este tiempo, una excepción es lanzada DeadlineExceededException:¿Cómo se implementa DeadlineExceededException en Google App Engine para Java?

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

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

+1

Para decirlo sin rodeos, ¿por qué te importa? –

+4

Uhm ...Porque los humanos son curiosos? – wds

+1

@Nick Johnson: porque puede ser útil para implementar en otras aplicaciones (alojadas automáticamente) donde la aplicación puede hacer muchas cosas con otros subsistemas (búsquedas de URL desde otros sitios, búsqueda de índice lucene enorme, interbloqueos en la base de datos) y puede es necesario evitar la inanición del hilo usando esta forma (fuerza bruta). – cherouvim

Respuesta

1

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

Sin embargo, puede utilizar esta función para redes o, en general, para cualquier código de E/S limitado usando java.nio (por ejemplo, Selector). En su lugar, para código de CPU limitado, puede usar java.util.concurrent (por ejemplo, Future).

3

The Request Timer

Un controlador de solicitudes tiene una cantidad limitada de tiempo para generar y devolver una respuesta a una solicitud , típicamente alrededor de 30 segundos. Una vez que se ha alcanzado el plazo , se interrumpe el controlador de solicitud .

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

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

Mientras que una solicitud puede tardar hasta 30 segundos en responder , App Engine es optimizado para aplicaciones con solicitudes de corta duración, por lo general los que tomar 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 escalará correctamente con la aplicación Infraestructura del motor.

Parte del tiempo de ejecución == No se utilizan subprocesos. Esta característica es una modificación de la máquina virtual con seguridad, y no aguantaría la respiración esperando el código fuente.

1

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

+1

La pregunta es cómo lo hace GAE. Google dice que está implementado en el tiempo de ejecución. http://code.google.com/appengine/docs/java/runtime.html#The_Request_Timer –

0

Puede ser una respuesta 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!"); 
    } 

} 
+0

La pregunta fue acerca de cómo se lanza la excepción para cada solicitud/servlet> 30s, no cómo atraparla. – Franck

+0

¡Hola, tranquilo, de acuerdo! –