Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make workflow-support compatible with Guava 21.0 and newer #114

Merged
merged 11 commits into from
Mar 4, 2021
2 changes: 1 addition & 1 deletion .mvn/extensions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.0-beta-4</version>
<version>1.2</version>
</extension>
</extensions>
7 changes: 4 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@
</license>
</licenses>
<scm>
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>
<connection>scm:git:git://github.com/${gitHubRepo}.git</connection>
<developerConnection>scm:git:git@github.com:${gitHubRepo}.git</developerConnection>
<url>https://github.com/${gitHubRepo}</url>
<tag>${scmTag}</tag>
</scm>
<repositories>
Expand All @@ -69,6 +69,7 @@
<no-test-jar>false</no-test-jar>
<useBeta>true</useBeta>
<hpi.compatibleSinceVersion>3.0</hpi.compatibleSinceVersion>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
</properties>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void run() {
ChainingListenableFuture.this.outputFuture = null;
}
}
}, MoreExecutors.sameThreadExecutor());
}, Futures.newExecutorService());
} catch (UndeclaredThrowableException e) {
// Set the cause of the exception as this future's exception
setException(e.getCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
import com.google.common.util.concurrent.SettableFuture;

import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
Expand Down Expand Up @@ -65,7 +68,7 @@ public abstract class Futures {
* });}</pre>
*
* <p>Note: This overload of {@code addCallback} is designed for cases in
* which the callack is fast and lightweight, as the method does not accept
* which the callback is fast and lightweight, as the method does not accept
* an {@code Executor} in which to perform the the work. For heavier
* callbacks, this overload carries some caveats: First, the thread that the
* callback runs in depends on whether the input {@code Future} is done at the
Expand All @@ -74,7 +77,7 @@ public abstract class Futures {
* callback in the thread that calls {@code addCallback} or {@code
* Future.cancel}. Second, callbacks may run in an internal thread of the
* system responsible for the input {@code Future}, such as an RPC network
* thread. Finally, during the execution of a {@code sameThreadExecutor}
* thread. Finally, during the execution of a {@code newExecutorService}
* callback, all other registered but unexecuted listeners are prevented from
* running, even if those listeners are to run in other executors.
*
Expand All @@ -87,7 +90,7 @@ public abstract class Futures {
*/
public static <V> void addCallback(ListenableFuture<V> future,
FutureCallback<? super V> callback) {
addCallback(future, callback, MoreExecutors.sameThreadExecutor());
addCallback(future, callback, newExecutorService());
}

/**
Expand Down Expand Up @@ -115,16 +118,16 @@ public static <V> void addCallback(ListenableFuture<V> future,
*
* When the callback is fast and lightweight consider {@linkplain
* Futures#addCallback(ListenableFuture, FutureCallback) the other overload}
* or explicit use of {@link MoreExecutors#sameThreadExecutor
* sameThreadExecutor}. For heavier callbacks, this choice carries some
* or explicit use of {@link #newExecutorService()}.
* For heavier callbacks, this choice carries some
* caveats: First, the thread that the callback runs in depends on whether
* the input {@code Future} is done at the time {@code addCallback} is called
* and on whether the input {@code Future} is ever cancelled. In particular,
* {@code addCallback} may execute the callback in the thread that calls
* {@code addCallback} or {@code Future.cancel}. Second, callbacks may run in
* an internal thread of the system responsible for the input {@code Future},
* such as an RPC network thread. Finally, during the execution of a {@code
* sameThreadExecutor} callback, all other registered but unexecuted
* newExecutorService} callback, all other registered but unexecuted
* listeners are prevented from running, even if those listeners are to run
* in other executors.
*
Expand Down Expand Up @@ -218,7 +221,7 @@ public static <V> ListenableFuture<V> immediateFailedFuture(
* thread that called {@code transform}. Second, transformations may run in
* an internal thread of the system responsible for the input {@code Future},
* such as an RPC network thread. Finally, during the execution of a {@code
* sameThreadExecutor} transformation, all other registered but unexecuted
* newExecutorService} transformation, all other registered but unexecuted
* listeners are prevented from running, even if those listeners are to run
* in other executors.
*
Expand All @@ -240,7 +243,7 @@ public static <V> ListenableFuture<V> immediateFailedFuture(
*/
public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
final Function<? super I, ? extends O> function) {
return Futures.<I, O>transform(future, function, MoreExecutors.sameThreadExecutor());
return Futures.<I, O>transform(future, function, newExecutorService());
}

/**
Expand Down Expand Up @@ -272,15 +275,15 @@ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
* <p>Note: For cases in which the transformation is fast and lightweight,
* consider {@linkplain Futures#transform(ListenableFuture, Function) the
* other overload} or explicit use of {@link
* MoreExecutors#sameThreadExecutor}. For heavier transformations, this
* #newExecutorService}. For heavier transformations, this
* choice carries some caveats: First, the thread that the transformation
* runs in depends on whether the input {@code Future} is done at the time
* {@code transform} is called. In particular, if called late, {@code
* transform} will perform the transformation in the thread that called
* {@code transform}. Second, transformations may run in an internal thread
* of the system responsible for the input {@code Future}, such as an RPC
* network thread. Finally, during the execution of a {@code
* sameThreadExecutor} transformation, all other registered but unexecuted
* newExecutorService} transformation, all other registered but unexecuted
* listeners are prevented from running, even if those listeners are to run
* in other executors.
*
Expand All @@ -304,6 +307,29 @@ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
return chain(future, wrapperFunction, executor);
}

/**
* Returns an {@link ExecutorService} to be used as a parameter in other methods.
* It calls {@code MoreExecutors#newDirectExecutorService} or falls back to {@code MoreExecutors#sameThreadExecutor}
* for compatibility with older (&lt; 18.0) versions of guava.
*
* @since TODO
*/
public static ExecutorService newExecutorService() {
try {
try {
// Guava older than 18
Method method = MoreExecutors.class.getMethod("sameThreadExecutor");
return (ExecutorService) method.invoke(null);
} catch (NoSuchMethodException e) {
// TODO invert this to prefer the newer guava method once guava is upgrade in Jenkins core
Method method = MoreExecutors.class.getMethod("newDirectExecutorService");
return (ExecutorService) method.invoke(null);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e ) {
throw new RuntimeException(e);
}
}

/**
* Creates a new {@code ListenableFuture} whose value is a list containing the
* values of all its input futures, if all succeed. If any input fails, the
Expand All @@ -324,7 +350,7 @@ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
public static <V> ListenableFuture<List<V>> allAsList(
ListenableFuture<? extends V>... futures) {
return new ListFuture<V>(ImmutableList.copyOf(futures), true,
MoreExecutors.sameThreadExecutor());
newExecutorService());
}

/**
Expand All @@ -347,7 +373,7 @@ public static <V> ListenableFuture<List<V>> allAsList(
public static <V> ListenableFuture<List<V>> allAsList(
Iterable<? extends ListenableFuture<? extends V>> futures) {
return new ListFuture<V>(ImmutableList.copyOf(futures), true,
MoreExecutors.sameThreadExecutor());
newExecutorService());
}

/**
Expand Down Expand Up @@ -379,14 +405,14 @@ public static <V> ListenableFuture<List<V>> allAsList(
* <p>Note: For cases in which the work of creating the derived future is
* fast and lightweight, consider {@linkplain Futures#chain(ListenableFuture,
* Function) the other overload} or explicit use of {@code
* sameThreadExecutor}. For heavier derivations, this choice carries some
* newExecutorService}. For heavier derivations, this choice carries some
* caveats: First, the thread that the derivation runs in depends on whether
* the input {@code Future} is done at the time {@code chain} is called. In
* particular, if called late, {@code chain} will run the derivation in the
* thread that called {@code chain}. Second, derivations may run in an
* internal thread of the system responsible for the input {@code Future},
* such as an RPC network thread. Finally, during the execution of a {@code
* sameThreadExecutor} {@code chain} function, all other registered but
* newExecutorService} {@code chain} function, all other registered but
* unexecuted listeners are prevented from running, even if those listeners
* are to run in other executors.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void run() {
// Let go of the memory held by other futures
ListFuture.this.futures = null;
}
}, MoreExecutors.sameThreadExecutor());
}, Futures.newExecutorService());

// Now begin the "real" initialization.

Expand Down