Skip to content

Commit

Permalink
Fix the logic that decides whether to use currentRequestThreadFactory…
Browse files Browse the repository at this point in the history
…() under App Engine.

While there, also support thread renaming under App Engine.

Fixes #3598
Relevant to #3606
(also, the CL in which I experimented with #3569 before backing it out)

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=272446666
  • Loading branch information
cpovirk committed Oct 2, 2019
1 parent 67dd062 commit e3ee00d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 38 deletions.
Expand Up @@ -129,9 +129,10 @@ public void run() {
/** Tries to set name of the given {@link Thread}, returns true if successful. */
@GwtIncompatible // threads
private static boolean trySetName(final String threadName, Thread currentThread) {
// In AppEngine, this will always fail. Should we test for that explicitly using
// MoreExecutors.isAppEngine? More generally, is there a way to see if we have the modifyThread
// permission without catching an exception?
/*
* setName should usually succeed, but the security manager can prohibit it. Is there a way to
* see if we have the modifyThread permission without catching an exception?
*/
try {
currentThread.setName(threadName);
return true;
Expand Down
Expand Up @@ -739,15 +739,17 @@ public void run() {
/**
* Returns a default thread factory used to create new threads.
*
* <p>On AppEngine, returns {@code ThreadManager.currentRequestThreadFactory()}. Otherwise,
* returns {@link Executors#defaultThreadFactory()}.
* <p>When running on AppEngine with access to <a
* href="https://cloud.google.com/appengine/docs/standard/java/javadoc/">AppEngine legacy
* APIs</a>, this method returns {@code ThreadManager.currentRequestThreadFactory()}. Otherwise,
* it returns {@link Executors#defaultThreadFactory()}.
*
* @since 14.0
*/
@Beta
@GwtIncompatible // concurrency
public static ThreadFactory platformThreadFactory() {
if (!isAppEngine()) {
if (!isAppEngineWithApiClasses()) {
return Executors.defaultThreadFactory();
}
try {
Expand All @@ -772,10 +774,15 @@ public static ThreadFactory platformThreadFactory() {
}

@GwtIncompatible // TODO
private static boolean isAppEngine() {
private static boolean isAppEngineWithApiClasses() {
if (System.getProperty("com.google.appengine.runtime.environment") == null) {
return false;
}
try {
Class.forName("com.google.appengine.api.utils.SystemProperty");
} catch (ClassNotFoundException e) {
return false;
}
try {
// If the current environment is null, we're not inside AppEngine.
return Class.forName("com.google.apphosting.api.ApiProxy")
Expand Down Expand Up @@ -833,10 +840,6 @@ static Thread newThread(String name, Runnable runnable) {
static Executor renamingDecorator(final Executor executor, final Supplier<String> nameSupplier) {
checkNotNull(executor);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try
return executor;
}
return new Executor() {
@Override
public void execute(Runnable command) {
Expand All @@ -862,10 +865,6 @@ static ExecutorService renamingDecorator(
final ExecutorService service, final Supplier<String> nameSupplier) {
checkNotNull(service);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try.
return service;
}
return new WrappingExecutorService(service) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
Expand Down Expand Up @@ -896,10 +895,6 @@ static ScheduledExecutorService renamingDecorator(
final ScheduledExecutorService service, final Supplier<String> nameSupplier) {
checkNotNull(service);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try.
return service;
}
return new WrappingScheduledExecutorService(service) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
Expand Down
Expand Up @@ -9,6 +9,7 @@
<inherits name="com.google.common.testing.Testing"/>
<inherits name="com.google.common.util.concurrent.Concurrent"/>
<inherits name="com.google.common.truth.Truth"/>
<inherits name="activation.Activation"/>
<entry-point class="com.google.common.util.concurrent.TestModuleEntryPoint"/>

<source path=""/>
Expand Down
7 changes: 4 additions & 3 deletions guava/src/com/google/common/util/concurrent/Callables.java
Expand Up @@ -129,9 +129,10 @@ public void run() {
/** Tries to set name of the given {@link Thread}, returns true if successful. */
@GwtIncompatible // threads
private static boolean trySetName(final String threadName, Thread currentThread) {
// In AppEngine, this will always fail. Should we test for that explicitly using
// MoreExecutors.isAppEngine? More generally, is there a way to see if we have the modifyThread
// permission without catching an exception?
/*
* setName should usually succeed, but the security manager can prohibit it. Is there a way to
* see if we have the modifyThread permission without catching an exception?
*/
try {
currentThread.setName(threadName);
return true;
Expand Down
27 changes: 11 additions & 16 deletions guava/src/com/google/common/util/concurrent/MoreExecutors.java
Expand Up @@ -814,15 +814,17 @@ public void run() {
/**
* Returns a default thread factory used to create new threads.
*
* <p>On AppEngine, returns {@code ThreadManager.currentRequestThreadFactory()}. Otherwise,
* returns {@link Executors#defaultThreadFactory()}.
* <p>When running on AppEngine with access to <a
* href="https://cloud.google.com/appengine/docs/standard/java/javadoc/">AppEngine legacy
* APIs</a>, this method returns {@code ThreadManager.currentRequestThreadFactory()}. Otherwise,
* it returns {@link Executors#defaultThreadFactory()}.
*
* @since 14.0
*/
@Beta
@GwtIncompatible // concurrency
public static ThreadFactory platformThreadFactory() {
if (!isAppEngine()) {
if (!isAppEngineWithApiClasses()) {
return Executors.defaultThreadFactory();
}
try {
Expand All @@ -847,10 +849,15 @@ public static ThreadFactory platformThreadFactory() {
}

@GwtIncompatible // TODO
private static boolean isAppEngine() {
private static boolean isAppEngineWithApiClasses() {
if (System.getProperty("com.google.appengine.runtime.environment") == null) {
return false;
}
try {
Class.forName("com.google.appengine.api.utils.SystemProperty");
} catch (ClassNotFoundException e) {
return false;
}
try {
// If the current environment is null, we're not inside AppEngine.
return Class.forName("com.google.apphosting.api.ApiProxy")
Expand Down Expand Up @@ -908,10 +915,6 @@ static Thread newThread(String name, Runnable runnable) {
static Executor renamingDecorator(final Executor executor, final Supplier<String> nameSupplier) {
checkNotNull(executor);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try
return executor;
}
return new Executor() {
@Override
public void execute(Runnable command) {
Expand All @@ -937,10 +940,6 @@ static ExecutorService renamingDecorator(
final ExecutorService service, final Supplier<String> nameSupplier) {
checkNotNull(service);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try.
return service;
}
return new WrappingExecutorService(service) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
Expand Down Expand Up @@ -971,10 +970,6 @@ static ScheduledExecutorService renamingDecorator(
final ScheduledExecutorService service, final Supplier<String> nameSupplier) {
checkNotNull(service);
checkNotNull(nameSupplier);
if (isAppEngine()) {
// AppEngine doesn't support thread renaming, so don't even try.
return service;
}
return new WrappingScheduledExecutorService(service) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
Expand Down

0 comments on commit e3ee00d

Please sign in to comment.