From cfabbd23413aaeb6158262efb4b45eabbe51daa5 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 30 Mar 2017 16:04:57 +1100 Subject: [PATCH] minor cleanups --- .../jetty/http2/client/HTTP2Client.java | 1 - .../org/eclipse/jetty/io/ManagedSelector.java | 2 +- .../jetty/util/thread/ExecutionStrategy.java | 52 +------------------ .../util/thread/strategy/EatWhatYouKill.java | 52 ++++++++++--------- .../strategy/ExecuteProduceConsume.java | 9 ---- .../util/thread/strategy/ProduceConsume.java | 9 ---- .../strategy/ProduceExecuteConsume.java | 9 ---- 7 files changed, 30 insertions(+), 104 deletions(-) diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java index fc9655d9273..f2c33bf3e63 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java @@ -129,7 +129,6 @@ public class HTTP2Client extends ContainerLifeCycle private int initialSessionRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE; private int initialStreamRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE; private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); - private ExecutionStrategy.Factory executionStrategyFactory = new ProduceConsume.Factory(); @Override protected void doStart() throws Exception diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index 299eaa11a6c..f8112ddedee 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -76,7 +76,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable _id = id; SelectorProducer producer = new SelectorProducer(); Executor executor = selectorManager.getExecutor(); - _strategy = new EatWhatYouKill(producer, executor, Invocable.InvocationType.NON_BLOCKING, Invocable.InvocationType.BLOCKING); + _strategy = new EatWhatYouKill(producer,executor); addBean(_strategy); setStopTimeout(5000); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java index fe1ab63684b..a5fb26e267a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java @@ -25,6 +25,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.strategy.EatWhatYouKill; import org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume; /** @@ -73,55 +74,4 @@ public interface ExecutionStrategy Runnable produce(); } - - /** - *

A factory for {@link ExecutionStrategy}.

- */ - public static interface Factory - { - /** - *

Creates a new {@link ExecutionStrategy}.

- * - * @param producer the execution strategy producer - * @param executor the execution strategy executor - * @return a new {@link ExecutionStrategy} - */ - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor); - - /** - * @return the default {@link ExecutionStrategy} - */ - public static Factory getDefault() - { - return DefaultExecutionStrategyFactory.INSTANCE; - } - } - - public static class DefaultExecutionStrategyFactory implements Factory - { - private static final Logger LOG = Log.getLogger(Factory.class); - private static final Factory INSTANCE = new DefaultExecutionStrategyFactory(); - - @Override - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor) - { - String strategy = System.getProperty(producer.getClass().getName() + ".ExecutionStrategy"); - if (strategy != null) - { - try - { - Class c = Loader.loadClass(strategy); - Constructor m = c.getConstructor(Producer.class, Executor.class); - LOG.info("Use {} for {}", c.getSimpleName(), producer.getClass().getName()); - return m.newInstance(producer, executor); - } - catch (Exception e) - { - LOG.warn(e); - } - } - - return new ExecuteProduceConsume(producer, executor); - } - } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/EatWhatYouKill.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/EatWhatYouKill.java index b01728e8dab..315724c00bd 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/EatWhatYouKill.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/EatWhatYouKill.java @@ -32,17 +32,30 @@ import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.Locker.Lock; /** - *

A strategy where the thread that produces will always run the resulting task.

- *

The strategy may then dispatch another thread to continue production.

- *

The strategy is also known by the nickname 'eat what you kill', which comes from - * the hunting ethic that says a person should not kill anything he or she does not - * plan on eating. In this case, the phrase is used to mean that a thread should - * not produce a task that it does not intend to run. By making producers run the - * task that they have just produced avoids execution delays and avoids parallel slow - * down by running the task in the same core, with good chances of having a hot CPU - * cache. It also avoids the creation of a queue of produced tasks that the system - * does not yet have capacity to consume, which can save memory and exert back - * pressure on producers.

+ *

A strategy where the thread that produces will run the resulting task if it + * is possible to do so without thread starvation.

+ * + *

This strategy preemptively dispatches a thread as a pending producer, so that + * when a thread produces a task it can immediately run the task and let the pending + * producer thread take over producing. If necessary another thread will be dispatched + * to replace the pending producing thread. When operating in this pattern, the + * sub-strategy is called Execute Produce Consume (EPC) + *

+ *

However, if the task produced uses the {@link Invocable} API to indicate that + * it will not block, then the strategy will run it directly, regardless of the + * presence of a pending producing thread and then resume producing after the + * task has completed. This sub-strategy is also used if the strategy has been + * configured with a maximum of 0 pending threads and the thread currently producing + * does not use the {@link Invocable} API to indicate that it will not block. + * When operating in this pattern, the sub-strategy is called + * ProduceConsume (PC). + *

+ *

If there is no pending producer thread available and if the task has not + * indicated it is non-blocking, then this strategy will dispatch the execution of + * the task and immediately continue producing. When operating in this pattern, the + * sub-strategy is called ProduceExecuteConsume (PEC). + *

+ * */ public class EatWhatYouKill extends AbstractLifeCycle implements ExecutionStrategy, Runnable { @@ -73,7 +86,7 @@ public class EatWhatYouKill extends AbstractLifeCycle implements ExecutionStrate public EatWhatYouKill(Producer producer, Executor executor, InvocationType preferredInvocationPEC, InvocationType preferredInvocationEPC) { - this(producer,executor,preferredInvocationPEC,preferredInvocationEPC,1); + this(producer,executor,preferredInvocationPEC,preferredInvocationEPC,Integer.getInteger("org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.maxProducersPending",1)); } public EatWhatYouKill(Producer producer, Executor executor, InvocationType preferredInvocationPEC, InvocationType preferredInvocationEPC, int maxProducersPending ) @@ -110,7 +123,7 @@ public class EatWhatYouKill extends AbstractLifeCycle implements ExecutionStrate LOG.debug("{} execute {}", this, produce); if (produce) - produceConsume(); + doProduce(); } @Override @@ -183,10 +196,10 @@ public class EatWhatYouKill extends AbstractLifeCycle implements ExecutionStrate } if (producing) - produceConsume(); + doProduce(); } - private void produceConsume() + private void doProduce() { boolean may_block_caller = !Invocable.isNonBlockingInvocation(); if (LOG.isDebugEnabled()) @@ -358,13 +371,4 @@ public class EatWhatYouKill extends AbstractLifeCycle implements ExecutionStrate produce(); } } - - public static class Factory implements ExecutionStrategy.Factory - { - @Override - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor) - { - return new EatWhatYouKill(producer, executor); - } - } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsume.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsume.java index 628f1e895a2..1a8d3666df6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsume.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsume.java @@ -249,13 +249,4 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable produce(); } } - - public static class Factory implements ExecutionStrategy.Factory - { - @Override - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor) - { - return new ExecuteProduceConsume(producer, executor); - } - } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceConsume.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceConsume.java index efb0141e0af..63b806ad22e 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceConsume.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceConsume.java @@ -106,15 +106,6 @@ public class ProduceConsume implements ExecutionStrategy, Runnable produce(); } - public static class Factory implements ExecutionStrategy.Factory - { - @Override - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor) - { - return new ProduceConsume(producer, executor); - } - } - private enum State { IDLE, PRODUCE, EXECUTE diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceExecuteConsume.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceExecuteConsume.java index e8c92712a2a..4e14596bc45 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceExecuteConsume.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceExecuteConsume.java @@ -107,15 +107,6 @@ public class ProduceExecuteConsume implements ExecutionStrategy produce(); } - public static class Factory implements ExecutionStrategy.Factory - { - @Override - public ExecutionStrategy newExecutionStrategy(Producer producer, Executor executor) - { - return new ProduceExecuteConsume(producer, executor); - } - } - private enum State { IDLE, PRODUCE, EXECUTE