1717package com .google .appengine .api ;
1818
1919import com .google .apphosting .api .ApiProxy ;
20+ import java .util .Optional ;
2021import java .util .concurrent .ThreadFactory ;
2122
2223/**
@@ -36,24 +37,21 @@ public final class ThreadManager {
3637 "com.google.appengine.api.ThreadManager.BACKGROUND_THREAD_FACTORY" ;
3738
3839 /**
39- * Returns a {@link ThreadFactory} that will create threads scoped
40- * to the current request. These threads will be interrupted at the
41- * end of the current request and must complete within the request
42- * deadline. If they fail to, the instance containing them may be
43- * terminated.
40+ * Returns a {@link ThreadFactory} which will create threads scoped to the current request. These
41+ * threads will be interrupted at the end of the current request and must complete within the
42+ * request deadline. If they fail to, the instance containing them may be terminated.
4443 *
45- * <p>The principal reason to use this method is so that the created
46- * threads can make App Engine API calls ({@code com.google.appengine.api.*}).
47- * In general, threads not associated with a request cannot make these API calls.
44+ * <p>The principal reason to use this method is so that the created threads can make App Engine
45+ * API calls ({@code com.google.appengine.api.*}). In general, threads not associated with a
46+ * request cannot make these API calls.
4847 *
49- * <p>The returned factory is typically used with a call like
50- * {@link java.util.concurrent.Executors#newCachedThreadPool(ThreadFactory)}.
51- * Do not use the {@link java.util.concurrent.ExecutorService ExecutorService} returned
52- * by this call after the request that created it has completed.
48+ * <p>The returned factory is typically used with a call like {@link
49+ * java.util.concurrent.Executors#newCachedThreadPool(ThreadFactory)}. Do not use the {@link
50+ * java.util.concurrent.ExecutorService ExecutorService} returned by this call after the request
51+ * that created it has completed.
5352 *
54- * <p>Note that calling {@link ThreadFactory#newThread} on the
55- * returned instance may throw any of the unchecked exceptions
56- * mentioned by {@link #createBackgroundThread}.
53+ * <p>Note that calling {@link ThreadFactory#newThread} on the returned instance may throw any of
54+ * the unchecked exceptions mentioned by {@link #createBackgroundThread}.
5755 *
5856 * @throws NullPointerException if the calling thread is not associated with a request.
5957 */
@@ -62,6 +60,34 @@ public static ThreadFactory currentRequestThreadFactory() {
6260 return (ThreadFactory ) environment .getAttributes ().get (REQUEST_THREAD_FACTORY_ATTR );
6361 }
6462
63+ /**
64+ * Returns an Optional {@link ThreadFactory} which will create threads scoped to the current
65+ * request. These threads will be interrupted at the end of the current request and must complete
66+ * within the request deadline. If they fail to, the instance containing them may be terminated.
67+ *
68+ * <p>If this method is not called from an App Engine request thread, returns an empty Optional
69+ * instance.
70+ *
71+ * <p>The principal reason to use this method is so that the created threads can make App Engine
72+ * API calls ({@code com.google.appengine.api.*}). In general, threads not associated with a
73+ * request cannot make these API calls.
74+ *
75+ * <p>The returned factory is typically used with a call like {@link
76+ * java.util.concurrent.Executors#newCachedThreadPool(ThreadFactory)}. Do not use the {@link
77+ * java.util.concurrent.ExecutorService ExecutorService} returned by this call after the request
78+ * that created it has completed.
79+ *
80+ * <p>Note that calling {@link ThreadFactory#newThread} on the returned instance may throw any of
81+ * the unchecked exceptions mentioned by {@link #createBackgroundThread}.
82+ */
83+ public static Optional <ThreadFactory > currentRequestThreadFactoryOptional () {
84+ return Optional .ofNullable (ApiProxy .getCurrentEnvironment ())
85+ .flatMap (
86+ environment ->
87+ Optional .ofNullable (
88+ (ThreadFactory ) environment .getAttributes ().get (REQUEST_THREAD_FACTORY_ATTR )));
89+ }
90+
6591 /**
6692 * Create a new {@link Thread} that executes {@code runnable} for
6793 * the duration of the current request. Calling this method is
0 commit comments