Top Description Inners Fields Constructors Methods
org.eclipse.jetty.util.thread.strategy

public Class AdaptiveExecutionStrategy

extends ContainerLifeCycle
implements ExecutionStrategy, Runnable
Class Inheritance
All Implemented Interfaces
java.lang.Runnable, org.eclipse.jetty.util.thread.ExecutionStrategy
Known Direct Subclasses
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill
Annotations
@ManagedObject:Adaptive execution strategy
Imports
java.io.Closeable, java.time.ZonedDateTime, java.time.format.DateTimeFormatter, java.util.concurrent.Executor, .RejectedExecutionException, java.util.concurrent.atomic.LongAdder, org.eclipse.jetty.util.AtomicBiInteger, .IO, .VirtualThreads, org.eclipse.jetty.util.annotation.ManagedAttribute, .ManagedObject, .ManagedOperation, org.eclipse.jetty.util.component.ContainerLifeCycle, org.eclipse.jetty.util.thread.ExecutionStrategy, .Invocable, .TryExecutor, org.slf4j.Logger, .LoggerFactory

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 with TryExecutor#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 many Invocable.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 allows AdaptiveExecutionStrategys 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 as Invocable.InvocationType#EITHER so when there are no pending producers threads available to the first strategy, then it may invoke the second as Invocable.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 and Inner Type Summary

Modifier and TypeClass and Description
private static enum
AdaptiveExecutionStrategy.SubStrategy

The sub-strategies used by the strategy to consume tasks that are produced.

Field Summary

Modifier and TypeField and Description
private final LongAdder
private final Executor
private final LongAdder
private final LongAdder
private final LongAdder
private final ExecutionStrategy.Producer
private final AtomicBiInteger
private final TryExecutor
private final Executor
private static final int
IDLE

The production state of the strategy.

private static final Logger
private static final int
private static final int

Constructor Summary

AccessConstructor and Description
public
AdaptiveExecutionStrategy(ExecutionStrategy.Producer
The producer of tasks to be consumed.
producer
,
Executor
The executor to be used for executing producers or consumers, depending on the sub-strategy.
executor
)

Method Summary

Modifier and TypeMethod and Description
private boolean

Returns:

True if the sub-strategy requires the caller to continue to produce tasks.
consumeTask
(Runnable
The task to consume.
task
,
AdaptiveExecutionStrategy.SubStrategy
The execution sub-strategy to use to consume the task.
subStrategy
)

Consumes a task with a sub-strategy.

public void
dispatch()

Implements org.eclipse.jetty.util.thread.ExecutionStrategy.dispatch.

Initiates (or resumes) the task production and consumption.

private void
execute(Runnable
The task to execute.
task
)

Executes a task via the Executor used to construct this strategy.

public long
public long
public long
public long
private void
getState(StringBuilder builder, long biState)

private void
private void
invokeAsNonBlocking(Runnable
The task to run in non-blocking mode.
task
)

Runs a task in non-blocking mode.

public boolean
public boolean
public void
produce()

Implements org.eclipse.jetty.util.thread.ExecutionStrategy.produce.

Initiates (or resumes) the task production and consumption.

private Runnable

Returns:

A produced task or null if there were no tasks or a Throwable was thrown.
produceTask
()

Produces a task, logging any Throwable that may result.

public void
public void
run()

Implements java.lang.Runnable.run.

Runs this operation.

private void
runTask(Runnable
The task to run.
task
)

Runs a Runnable task, logging any thrown exception.

private AdaptiveExecutionStrategy.SubStrategy

Returns:

The sub-strategy to use for the task.
selectSubStrategy
(Runnable
The task to select the strategy for.
task
,
boolean
True if the producing thread cannot block.
nonBlocking
)

Selects the execution strategy.

public String
toString()

Overrides org.eclipse.jetty.util.component.AbstractLifeCycle.toString.

Returns a string representation of the object.

public String
toString(long biState)

private void
tryProduce(boolean
True if the calling thread was started as a pending producer.
wasPending
)

Tries to become the producing thread and then produces and consumes tasks.

Inherited from org.eclipse.jetty.util.component.ContainerLifeCycle:
addBeanaddBeanaddEventListeneraddManagedcontainsdestroydoStartdoStopdumpdumpdumpdumpObjectsdumpStdErrgetBeangetBeansgetBeansgetContainedBeansgetContainedBeansisAutoisManagedisUnmanagedmanageremoveBeanremoveBeansremoveEventListenersetBeansstartstopunmanageupdateBeanupdateBeanupdateBeansupdateBeans

Field Detail

_epcModeback to summary
private final LongAdder _epcMode
_executorback to summary
private final Executor _executor
_pcModeback to summary
private final LongAdder _pcMode
_pecModeback to summary
private final LongAdder _pecMode
_picModeback to summary
private final LongAdder _picMode
_producerback to summary
private final ExecutionStrategy.Producer _producer
_stateback to summary
private final AtomicBiInteger _state

Hides org.eclipse.jetty.util.component.AbstractLifeCycle._state.

_tryExecutorback to summary
private final TryExecutor _tryExecutor
_virtualExecutorback to summary
private final Executor _virtualExecutor
IDLEback to summary
private static final int IDLE

The production state of the strategy.

LOGback to summary
private static final Logger LOG

Hides org.eclipse.jetty.util.component.ContainerLifeCycle.LOG.

PRODUCINGback to summary
private static final int PRODUCING
REPRODUCINGback to summary
private static final int REPRODUCING

Constructor Detail

AdaptiveExecutionStrategyback to summary
public AdaptiveExecutionStrategy(ExecutionStrategy.Producer producer, Executor executor)
Parameters
producer:ExecutionStrategy.Producer

The producer of tasks to be consumed.

executor:Executor

The executor to be used for executing producers or consumers, depending on the sub-strategy.

Method Detail

consumeTaskback to summary
private boolean consumeTask(Runnable task, AdaptiveExecutionStrategy.SubStrategy subStrategy)

Consumes a task with a sub-strategy.

Parameters
task:Runnable

The task to consume.

subStrategy:AdaptiveExecutionStrategy.SubStrategy

The execution sub-strategy to use to consume the task.

Returns:boolean

True if the sub-strategy requires the caller to continue to produce tasks.

dispatchback to summary
public void dispatch()

Implements org.eclipse.jetty.util.thread.ExecutionStrategy.dispatch.

Doc from org.eclipse.jetty.util.thread.ExecutionStrategy.dispatch.

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)
Annotations
@Override
executeback to summary
private void execute(Runnable task)

Executes a task via the Executor used to construct this strategy. If the execution is rejected and the task is a Closeable, then it is closed.

Parameters
task:Runnable

The task to execute.

getEPCTasksConsumedback to summary
public long getEPCTasksConsumed()
Annotations
@ManagedAttribute:number of tasks consumed with EPC mode
readonly:true
getPCTasksConsumedback to summary
public long getPCTasksConsumed()
Annotations
@ManagedAttribute:number of tasks consumed with PC mode
readonly:true
getPECTasksExecutedback to summary
public long getPECTasksExecuted()
Annotations
@ManagedAttribute:number of tasks executed with PEC mode
readonly:true
getPICTasksExecutedback to summary
public long getPICTasksExecuted()
Annotations
@ManagedAttribute:number of tasks executed with PIC mode
readonly:true
getStateback to summary
private void getState(StringBuilder builder, long biState)
getStringback to summary
private void getString(StringBuilder builder)
invokeAsNonBlockingback to summary
private void invokeAsNonBlocking(Runnable task)

Runs a task in non-blocking mode.

Parameters
task:Runnable

The task to run in non-blocking mode.

isIdleback to summary
public boolean isIdle()
Annotations
@ManagedAttribute:whether this execution strategy is idle
readonly:true
isUseVirtualThreadsback to summary
public boolean isUseVirtualThreads()
Annotations
@ManagedAttribute:whether this execution strategy uses virtual threads
readonly:true
produceback to summary
public void produce()

Implements org.eclipse.jetty.util.thread.ExecutionStrategy.produce.

Doc from org.eclipse.jetty.util.thread.ExecutionStrategy.produce.

Initiates (or resumes) the task production and consumption.

The produced task may be run by the same thread that called this method.

Annotations
@Override
produceTaskback to summary
private Runnable produceTask()

Produces a task, logging any Throwable that may result.

Returns:Runnable

A produced task or null if there were no tasks or a Throwable was thrown.

resetback to summary
public void reset()
Annotations
@ManagedOperation:resets the task counts
impact:ACTION
runback to summary
public void run()

Implements java.lang.Runnable.run.

Doc from java.lang.Runnable.run.

Runs this operation.

Annotations
@Override
runTaskback to summary
private void runTask(Runnable task)

Runs a Runnable task, logging any thrown exception.

Parameters
task:Runnable

The task to run.

selectSubStrategyback to summary
private AdaptiveExecutionStrategy.SubStrategy selectSubStrategy(Runnable task, boolean nonBlocking)

Selects the execution strategy.

Parameters
task:Runnable

The task to select the strategy for.

nonBlocking:boolean

True if the producing thread cannot block.

Returns:AdaptiveExecutionStrategy.SubStrategy

The sub-strategy to use for the task.

toStringback to summary
public String toString()

Overrides org.eclipse.jetty.util.component.AbstractLifeCycle.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Returns:String

a string representation of the object

Annotations
@Override
toStringback to summary
public String toString(long biState)
tryProduceback to summary
private void tryProduce(boolean wasPending)

Tries to become the producing thread and then produces and consumes tasks.

Parameters
wasPending:boolean

True if the calling thread was started as a pending producer.

org.eclipse.jetty.util.thread.strategy back to summary

private final Enum AdaptiveExecutionStrategy.SubStrategy

extends Enum<AdaptiveExecutionStrategy.SubStrategy>
Class Inheritance

The sub-strategies used by the strategy to consume tasks that are produced.

Field Summary

Modifier and TypeField and Description
public static final AdaptiveExecutionStrategy.SubStrategy
EXECUTE_PRODUCE_CONSUME

Executes a pending producer, consumes produced tasks and races the pending producer to continue producing.

public static final AdaptiveExecutionStrategy.SubStrategy
PRODUCE_CONSUME

Consumes produced tasks and continues producing.

public static final AdaptiveExecutionStrategy.SubStrategy
PRODUCE_EXECUTE_CONSUME

Executes produced tasks and continues producing.

public static final AdaptiveExecutionStrategy.SubStrategy
PRODUCE_INVOKE_CONSUME

Consumes produced tasks as non blocking and continues producing.

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public static AdaptiveExecutionStrategy.SubStrategy
public static AdaptiveExecutionStrategy.SubStrategy[]
Inherited from java.lang.Enum:
clonecompareTodescribeConstableequalsfinalizegetDeclaringClasshashCodenameordinaltoStringvalueOf

Field Detail

EXECUTE_PRODUCE_CONSUMEback to summary
public static final AdaptiveExecutionStrategy.SubStrategy EXECUTE_PRODUCE_CONSUME

Executes a pending producer, consumes produced tasks and races the pending producer to continue producing.

PRODUCE_CONSUMEback to summary
public static final AdaptiveExecutionStrategy.SubStrategy PRODUCE_CONSUME

Consumes produced tasks and continues producing.

PRODUCE_EXECUTE_CONSUMEback to summary
public static final AdaptiveExecutionStrategy.SubStrategy PRODUCE_EXECUTE_CONSUME

Executes produced tasks and continues producing.

PRODUCE_INVOKE_CONSUMEback to summary
public static final AdaptiveExecutionStrategy.SubStrategy PRODUCE_INVOKE_CONSUME

Consumes produced tasks as non blocking and continues producing.

Constructor Detail

SubStrategyback to summary
private SubStrategy()

Method Detail

valueOfback to summary
public static AdaptiveExecutionStrategy.SubStrategy valueOf(String name)
valuesback to summary
public static AdaptiveExecutionStrategy.SubStrategy[] values()