Class AdaptiveExecutionStrategy
- java.lang.Object
-
- org.eclipse.jetty.util.component.AbstractLifeCycle
-
- org.eclipse.jetty.util.component.ContainerLifeCycle
-
- org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy
-
- All Implemented Interfaces:
Container
,Destroyable
,Dumpable
,Dumpable.DumpableContainer
,LifeCycle
,ExecutionStrategy
- Direct Known Subclasses:
EatWhatYouKill
@ManagedObject("Adaptive execution strategy") public class AdaptiveExecutionStrategy extends ContainerLifeCycle implements ExecutionStrategy
An adaptive execution strategy that uses the
Invocable
status of both the task and the current thread to select an optimal strategy that prioritizes executing the task immediately in the current producing thread if it can be done so without thread starvation issues.This strategy selects between the following sub-strategies:
- ProduceConsume(PC)
- The producing thread consumes the task by running it directly and then continues to produce.
- ProduceInvokeConsume(PIC)
- The producing thread consumes the task by running it with
Invocable.invokeNonBlocking(Runnable)
and then continues to produce. - ProduceExecuteConsume(PEC)
- The producing thread dispatches the task to a thread pool to be executed and then continues to produce.
- ExecuteProduceConsume(EPC)
- The producing thread consumes dispatches a pending producer to a thread pool, then consumes the task by running it directly (as in PC mode), then races with the pending producer thread to take over production.
The sub-strategy is selected as follows:
- PC
- If the produced task is
Invocable.InvocationType.NON_BLOCKING
. - EPC
- If the producing thread is not
Invocable.InvocationType.NON_BLOCKING
and a pending producer thread is available, either because there is already a pending producer or one is successfully started withTryExecutor.tryExecute(Runnable)
. - PIC
- If the produced task is
Invocable.InvocationType.EITHER
and EPC was not selected. - PEC
- Otherwise.
Because of the preference for
PC
mode, on a multicore machine with many manyInvocable.InvocationType.NON_BLOCKING
tasks, multiple instances of the strategy may be required to keep all CPUs on the system busy.Since the producing thread may be invoked with
Invocable.invokeNonBlocking(Runnable)
this allowsAdaptiveExecutionStrategy
s to be efficiently and safely chained: a task produced by one execution strategy may become itself be a producer in a second execution strategy (e.g. an IO selector may use an execution strategy to handle multiple connections and each connection may use a execution strategy to handle multiplexed channels/streams within the connection).A task containing another
AdaptiveExecutionStrategy
should identify asInvocable.InvocationType.EITHER
so when there are no pending producers threads available to the first strategy, then it may invoke the second asInvocable.InvocationType.NON_BLOCKING
. This avoids starvation as the production on the second strategy can always be executed, but without the risk that it may block the last available producer for the first strategy.This strategy was previously named EatWhatYouKill (EWYK) because its preference for a producer to directly consume the tasks that it produces is similar to a hunting proverb that says that a hunter should eat (i.e. consume) what they kill (i.e. produced).
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
AbstractLifeCycle.AbstractLifeCycleListener, AbstractLifeCycle.StopException
-
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.Container
Container.InheritedListener, Container.Listener
-
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.Dumpable
Dumpable.DumpableContainer
-
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.thread.ExecutionStrategy
ExecutionStrategy.Producer
-
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.LifeCycle
LifeCycle.Listener
-
-
Constructor Summary
Constructors Constructor Description AdaptiveExecutionStrategy(ExecutionStrategy.Producer producer, java.util.concurrent.Executor executor)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
dispatch()
Initiates (or resumes) the task production and consumption.long
getEPCTasksConsumed()
long
getPCTasksConsumed()
long
getPECTasksExecuted()
long
getPICTasksExecuted()
boolean
isIdle()
void
produce()
Initiates (or resumes) the task production and consumption.void
reset()
java.lang.String
toString()
java.lang.String
toStringLocked()
-
Methods inherited from class org.eclipse.jetty.util.component.ContainerLifeCycle
addBean, addBean, addEventListener, addManaged, contains, destroy, doStart, doStop, dump, dump, dump, dumpObjects, dumpStdErr, getBean, getBeans, getBeans, getContainedBeans, getContainedBeans, isAuto, isManaged, isUnmanaged, manage, removeBean, removeBeans, removeEventListener, setBeans, start, stop, unmanage, updateBean, updateBean, updateBeans, updateBeans
-
Methods inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
getEventListeners, getState, getState, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, setEventListeners, start, stop
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.eclipse.jetty.util.component.Container
getCachedBeans, getEventListeners
-
Methods inherited from interface org.eclipse.jetty.util.component.Dumpable.DumpableContainer
isDumpable
-
-
-
-
Constructor Detail
-
AdaptiveExecutionStrategy
public AdaptiveExecutionStrategy(ExecutionStrategy.Producer producer, java.util.concurrent.Executor executor)
- Parameters:
producer
- The produce of tasks to be consumed.executor
- The executor to be used for executing producers or consumers, depending on the sub-strategy.
-
-
Method Detail
-
dispatch
public void dispatch()
Description copied from interface:ExecutionStrategy
Initiates (or resumes) the task production and consumption.
This method guarantees that the task is never run by the thread that called this method.
TODO review the need for this (only used by HTTP2 push)- Specified by:
dispatch
in interfaceExecutionStrategy
- See Also:
ExecutionStrategy.produce()
-
produce
public void produce()
Description copied from interface:ExecutionStrategy
Initiates (or resumes) the task production and consumption.
The produced task may be run by the same thread that called this method.
- Specified by:
produce
in interfaceExecutionStrategy
- See Also:
ExecutionStrategy.dispatch()
-
getPCTasksConsumed
@ManagedAttribute(value="number of tasks consumed with PC mode", readonly=true) public long getPCTasksConsumed()
-
getPICTasksExecuted
@ManagedAttribute(value="number of tasks executed with PIC mode", readonly=true) public long getPICTasksExecuted()
-
getPECTasksExecuted
@ManagedAttribute(value="number of tasks executed with PEC mode", readonly=true) public long getPECTasksExecuted()
-
getEPCTasksConsumed
@ManagedAttribute(value="number of tasks consumed with EPC mode", readonly=true) public long getEPCTasksConsumed()
-
isIdle
@ManagedAttribute(value="whether this execution strategy is idle", readonly=true) public boolean isIdle()
-
reset
@ManagedOperation(value="resets the task counts", impact="ACTION") public void reset()
-
toString
public java.lang.String toString()
- Overrides:
toString
in classAbstractLifeCycle
-
toStringLocked
public java.lang.String toStringLocked()
-
-