diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index a2d496cc..43d62816 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -2,6 +2,6 @@ io.jenkins.tools.incrementals git-changelist-maven-extension - 1.0-beta-4 + 1.2 diff --git a/pom.xml b/pom.xml index e93dcf5a..861ceb33 100644 --- a/pom.xml +++ b/pom.xml @@ -44,9 +44,9 @@ - scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git - scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git - https://github.com/jenkinsci/${project.artifactId}-plugin + scm:git:git://github.com/${gitHubRepo}.git + scm:git:git@github.com:${gitHubRepo}.git + https://github.com/${gitHubRepo} ${scmTag} @@ -64,17 +64,18 @@ 2.42 -SNAPSHOT - 2.176.4 + 2.222.4 8 false true + jenkinsci/${project.artifactId}-plugin io.jenkins.tools.bom - bom-2.176.x - 16 + bom-2.222.x + 25 import pom diff --git a/src/main/java/org/jenkinsci/plugins/workflow/flow/DirectExecutor.java b/src/main/java/org/jenkinsci/plugins/workflow/flow/DirectExecutor.java new file mode 100644 index 00000000..fdf1532a --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/flow/DirectExecutor.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.jenkinsci.plugins.workflow.flow; + +import com.google.common.annotations.GwtCompatible; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import java.util.concurrent.Executor; + +/** + * An {@link Executor} that runs each task in the thread that invokes {@link Executor#execute + * execute}. + */ +@GwtCompatible +@Restricted(NoExternalUse.class) +enum DirectExecutor implements Executor { + INSTANCE; + + @Override + public void execute(Runnable command) { + command.run(); + } + + @Override + public String toString() { + return "MoreExecutors.directExecutor()"; + } +} \ No newline at end of file diff --git a/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java b/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java index e33661d1..0e20f266 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java @@ -194,7 +194,7 @@ public void onFailure(Throwable t) { LOGGER.log(WARNING, "Failed to load " + e, t); } } - }); + }, MoreExecutors.directExecutor()); } } } @@ -230,7 +230,7 @@ public void onSuccess(List result) { public void onFailure(Throwable t) { LOGGER.log(Level.WARNING, null, t); } - }); + }, MoreExecutors.directExecutor()); } return Futures.allAsList(all); @@ -253,5 +253,4 @@ public void onFailure(Throwable t) { executor.shutdown(); executor.awaitTermination(1, TimeUnit.MINUTES); } - } diff --git a/src/main/java/org/jenkinsci/plugins/workflow/flow/MoreExecutors.java b/src/main/java/org/jenkinsci/plugins/workflow/flow/MoreExecutors.java new file mode 100644 index 00000000..86e05657 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/workflow/flow/MoreExecutors.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.jenkinsci.plugins.workflow.flow; + +import com.google.common.annotations.GwtCompatible; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; + +/** + * Factory and utility methods for {@link java.util.concurrent.Executor}, {@link ExecutorService}, + * and {@link java.util.concurrent.ThreadFactory}. + * + * @author Eric Fellheimer + * @author Kyle Littlefield + * @author Justin Mahoney + * @since 3.0 + */ +@GwtCompatible(emulated = true) +@Restricted(NoExternalUse.class) +public final class MoreExecutors { + private MoreExecutors() {} + + /** + * Returns an {@link Executor} that runs each task in the thread that invokes {@link + * Executor#execute execute}, as in {@code ThreadPoolExecutor.CallerRunsPolicy}. + * + *

This executor is appropriate for tasks that are lightweight and not deeply chained. + * Inappropriate {@code directExecutor} usage can cause problems, and these problems can be + * difficult to reproduce because they depend on timing. For example: + * + *

    + *
  • A call like {@code future.transform(function, directExecutor())} may execute the function + * immediately in the thread that is calling {@code transform}. (This specific case happens + * if the future is already completed.) If {@code transform} call was made from a UI thread + * or other latency-sensitive thread, a heavyweight function can harm responsiveness. + *
  • If the task will be executed later, consider which thread will trigger the execution -- + * since that thread will execute the task inline. If the thread is a shared system thread + * like an RPC network thread, a heavyweight task can stall progress of the whole system or + * even deadlock it. + *
  • If many tasks will be triggered by the same event, one heavyweight task may delay other + * tasks -- even tasks that are not themselves {@code directExecutor} tasks. + *
  • If many such tasks are chained together (such as with {@code + * future.transform(...).transform(...).transform(...)....}), they may overflow the stack. + * (In simple cases, callers can avoid this by registering all tasks with the same {@code + * MoreExecutors#newSequentialExecutor} wrapper around {@code directExecutor()}. More + * complex cases may require using thread pools or making deeper changes.) + *
+ * + * Additionally, beware of executing tasks with {@code directExecutor} while holding a lock. Since + * the task you submit to the executor (or any other arbitrary work the executor does) may do slow + * work or acquire other locks, you risk deadlocks. + * + *

This instance is equivalent to: + * + *

{@code
+   * final class DirectExecutor implements Executor {
+   *   public void execute(Runnable r) {
+   *     r.run();
+   *   }
+   * }
+   * }
+ * + *

This should be preferred to {@code #newDirectExecutorService()} because implementing the + * {@link ExecutorService} subinterface necessitates significant performance overhead. + * + * + * @since 18.0 + */ + public static Executor directExecutor() { + return DirectExecutor.INSTANCE; + } +} \ No newline at end of file