/** * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS-IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.apphosting.tests.usercode.testservlets; import com.google.apphosting.api.ApiBasePb.Integer32Proto; import com.google.apphosting.api.ApiProxy; import com.google.apphosting.api.DeadlineExceededException; import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SleepServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { String sleepParam = req.getParameter("time"); int sleepMillis = (sleepParam != null) ? Integer.valueOf(sleepParam) : req.getIntHeader("Sleep-Time"); String retryOnApiException = req.getHeader("Retry-On-Api-Exception"); String retryOnSoftException = req.getHeader("Retry-On-Soft-Exception"); String retryOnErrors = req.getHeader("Retry-On-Errors"); String useBusyLoop = req.getHeader("Use-Busy-Loop"); String useSleepApi = req.getHeader("Use-Sleep-Api"); String useAsyncSleepApi = req.getHeader("Use-Async-Sleep-Api"); String sleepApiMethod = req.getHeader("Sleep-Api-Method"); if (sleepApiMethod == null) { sleepApiMethod = "Delay"; } res.setContentType("text/plain"); res.getWriter().println("Starting..."); // This print is actually a hack so that the System_ mirror // initialization happens before we waste all of our time sleeping // and don't have any time left to clean up properly. // // TODO(xx): Should we be pre-initializing the mirrors // somehow so that this isn't even an issue? It's likely to // confuse users if the first time they print or log is after a // DeadlineExceededException. System.err.println("About to sleep for " + sleepMillis); boolean keepGoing = true; while (keepGoing) { try { if (useBusyLoop != null) { long end = System.nanoTime() + sleepMillis * 1000000; long l; while ((l = System.nanoTime()) < end) { for (int i = 0; i < 65535; i++) { // Busy wait } } } else if (useSleepApi != null) { Integer32Proto intRequest = new Integer32Proto(); intRequest.setValue(sleepMillis); ApiProxy.makeSyncCall("google.util", sleepApiMethod, intRequest.toByteArray()); } else if (useAsyncSleepApi != null) { Integer32Proto intRequest = new Integer32Proto(); intRequest.setValue(sleepMillis); // Make an async call but ignore the response. ApiProxy.makeAsyncCall("google.util", sleepApiMethod, intRequest.toByteArray()); } else { Thread.sleep(sleepMillis); } keepGoing = false; } catch (InterruptedException ex) { System.err.println("Caught: " + ex); } catch (ApiProxy.ApiDeadlineExceededException ex) { System.err.println("Caught: " + ex); if (retryOnApiException == null) { throw ex; } } catch (DeadlineExceededException ex) { System.err.println("Caught: " + ex); if (retryOnSoftException == null) { throw ex; } } catch (Error ex) { System.err.println("Caught: " + ex); if (retryOnErrors == null) { throw ex; } } } res.getWriter().println("Done."); } }