App Engine SDK 1.8.4 release.
[gae.git] / java / src / main / com / google / appengine / tools / development / BackgroundThreadFactory.java
blobbe24873fd668c6578a215dec0ec1ee2a438af1bf
1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com.google.appengine.tools.development;
5 import com.google.apphosting.api.ApiProxy;
7 import java.security.AccessController;
8 import java.security.PrivilegedAction;
9 import java.util.concurrent.ThreadFactory;
10 import java.util.logging.Level;
11 import java.util.logging.Logger;
13 /**
14 * This {@link ThreadFactory} creates {@link Thread} objects that
15 * live independent of the current request. This means that they
16 * receive their own {@code LocalEnvironment} and have their own set
17 * of request ID and {@link RequestEndListener} objects.
20 public class BackgroundThreadFactory implements ThreadFactory {
21 private static final Logger logger = Logger.getLogger(BackgroundThreadFactory.class.getName());
23 private static final int API_CALL_LATENCY_MS = 20;
24 private static final int THREAD_STARTUP_LATENCY_MS = 20;
26 private final String appId;
27 private final String moduleName;
28 private final String majorVersionId;
30 public BackgroundThreadFactory(String appId, String moduleName, String majorVersionId) {
31 this.appId = appId;
32 this.moduleName = moduleName;
33 this.majorVersionId = majorVersionId;
36 @Override
37 public Thread newThread(final Runnable runnable) {
38 final LocalBackgroundEnvironment environment =
39 new LocalBackgroundEnvironment(appId, moduleName, majorVersionId,
40 LocalEnvironment.getCurrentInstance(), LocalEnvironment.getCurrentPort());
42 final boolean callerNativeMode = DevSocketImplFactory.isNativeSocketMode();
44 sleepUninterruptably(API_CALL_LATENCY_MS);
45 return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
46 @Override
47 public Thread run() {
48 Thread thread = new Thread(runnable) {
49 @Override
50 public void run() {
51 sleepUninterruptably(THREAD_STARTUP_LATENCY_MS);
52 DevSocketImplFactory.setSocketNativeMode(callerNativeMode);
53 ApiProxy.setEnvironmentForCurrentThread(environment);
54 try {
55 runnable.run();
56 } finally {
57 environment.callRequestEndListeners();
61 System.setProperty("devappserver-thread-" + thread.getName(), "true");
62 return thread;
64 });
67 final String getAppId() {
68 return appId;
71 private void sleepUninterruptably(long sleepMillis) {
72 try {
73 Thread.sleep(sleepMillis);
74 } catch (InterruptedException ex) {
75 logger.log(Level.INFO, "Interrupted simulating latency:", ex);
76 Thread.currentThread().interrupt();
80 private static class LocalBackgroundEnvironment extends LocalEnvironment {
81 public LocalBackgroundEnvironment(String appId, String moduleName,
82 String majorVersionId, int instance, int port) {
83 super(appId, moduleName, majorVersionId, instance, port, null);
86 @Override
87 public String getEmail() {
88 return null;
91 @Override
92 public boolean isLoggedIn() {
93 return false;
96 @Override
97 public boolean isAdmin() {
98 return false;