AutoScalingEventExecutorChooser Class — netty Architecture
Architecture documentation for the AutoScalingEventExecutorChooser class in AutoScalingEventExecutorChooserFactory.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD bb4797cf_7318_6bbb_4c87_1f53888dd980["AutoScalingEventExecutorChooser"] 409fa4eb_44da_665a_7f39_b9b5f929789e["AutoScalingEventExecutorChooserFactory.java"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|defined in| 409fa4eb_44da_665a_7f39_b9b5f929789e c4b40701_4326_dfe6_f06e_30628fb77b04["AutoScalingEventExecutorChooser()"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|method| c4b40701_4326_dfe6_f06e_30628fb77b04 178c3324_6aa0_719a_b4ab_65660a5ce63c["EventExecutor()"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|method| 178c3324_6aa0_719a_b4ab_65660a5ce63c a4304eb6_db6c_91df_93c2_2b3acb53fc85["tryScaleUpBy()"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|method| a4304eb6_db6c_91df_93c2_2b3acb53fc85 07fd7ee2_1ff7_6bde_d1c3_009b67256717["activeExecutorCount()"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|method| 07fd7ee2_1ff7_6bde_d1c3_009b67256717 70c7dffa_2836_7cea_ddab_508d8f03649b["executorUtilizations()"] bb4797cf_7318_6bbb_4c87_1f53888dd980 -->|method| 70c7dffa_2836_7cea_ddab_508d8f03649b
Relationship Graph
Source Code
common/src/main/java/io/netty/util/concurrent/AutoScalingEventExecutorChooserFactory.java lines 155–420
private final class AutoScalingEventExecutorChooser implements ObservableEventExecutorChooser {
private final EventExecutor[] executors;
private final EventExecutorChooser allExecutorsChooser;
private final AtomicReference<AutoScalingState> state;
private final List<AutoScalingUtilizationMetric> utilizationMetrics;
AutoScalingEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
List<AutoScalingUtilizationMetric> metrics = new ArrayList<>(executors.length);
for (EventExecutor executor : executors) {
metrics.add(new AutoScalingUtilizationMetric(executor));
}
utilizationMetrics = Collections.unmodifiableList(metrics);
allExecutorsChooser = DefaultEventExecutorChooserFactory.INSTANCE.newChooser(executors);
AutoScalingState initialState = new AutoScalingState(maxChildren, 0L, executors);
state = new AtomicReference<>(initialState);
ScheduledFuture<?> utilizationMonitoringTask = GlobalEventExecutor.INSTANCE.scheduleAtFixedRate(
new UtilizationMonitor(), utilizationCheckPeriodNanos, utilizationCheckPeriodNanos,
TimeUnit.NANOSECONDS);
if (executors.length > 0) {
executors[0].terminationFuture().addListener(future -> utilizationMonitoringTask.cancel(false));
}
}
/**
* This method is only responsible for picking from the active executors list.
* The monitor handles all scaling decisions.
*/
@Override
public EventExecutor next() {
// Get a snapshot of the current state.
AutoScalingState currentState = this.state.get();
if (currentState.activeExecutors.length == 0) {
// This is only reachable if minChildren is 0 and the monitor has just suspended the last active thread.
// To prevent an error and ensure the group can recover, we wake one up and use the
// chooser that contains all executors as a safe temporary choice.
tryScaleUpBy(1);
return allExecutorsChooser.next();
}
return currentState.activeExecutorsChooser.next();
}
/**
* Tries to increase the active thread count by waking up suspended executors.
* This method is thread-safe and updates the state atomically.
*
* @param amount The desired number of threads to add to the active count.
*/
private void tryScaleUpBy(int amount) {
if (amount <= 0) {
return;
}
for (;;) {
AutoScalingState oldState = state.get();
if (oldState.activeChildrenCount >= maxChildren) {
return;
}
int canAdd = Math.min(amount, maxChildren - oldState.activeChildrenCount);
List<EventExecutor> wokenUp = new ArrayList<>(canAdd);
final long startIndex = oldState.nextWakeUpIndex;
for (int i = 0; i < executors.length; i++) {
EventExecutor child = executors[(int) Math.abs((startIndex + i) % executors.length)];
if (wokenUp.size() >= canAdd) {
break; // We have woken up all the threads we reserved.
}
if (child instanceof SingleThreadEventExecutor) {
SingleThreadEventExecutor stee = (SingleThreadEventExecutor) child;
if (stee.isSuspended()) {
stee.execute(NO_OOP_TASK);
wokenUp.add(stee);
}
}
}
Defined In
Source
Frequently Asked Questions
What is the AutoScalingEventExecutorChooser class?
AutoScalingEventExecutorChooser is a class in the netty codebase, defined in common/src/main/java/io/netty/util/concurrent/AutoScalingEventExecutorChooserFactory.java.
Where is AutoScalingEventExecutorChooser defined?
AutoScalingEventExecutorChooser is defined in common/src/main/java/io/netty/util/concurrent/AutoScalingEventExecutorChooserFactory.java at line 155.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free