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
;
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
) {
32 this.moduleName
= moduleName
;
33 this.majorVersionId
= majorVersionId
;
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
>() {
48 Thread thread
= new Thread(runnable
) {
51 sleepUninterruptably(THREAD_STARTUP_LATENCY_MS
);
52 DevSocketImplFactory
.setSocketNativeMode(callerNativeMode
);
53 ApiProxy
.setEnvironmentForCurrentThread(environment
);
57 environment
.callRequestEndListeners();
61 System
.setProperty("devappserver-thread-" + thread
.getName(), "true");
67 final String
getAppId() {
71 private void sleepUninterruptably(long sleepMillis
) {
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);
87 public String
getEmail() {
92 public boolean isLoggedIn() {
97 public boolean isAdmin() {