Skip to content

Commit

Permalink
Remove non-virtual executor support
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Aleksandrov <dmitry.aleksandrov@oracle.com>
  • Loading branch information
dalexandrov committed Aug 7, 2023
1 parent c34adae commit 21a2b83
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 903 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
package io.helidon.common.configurable;

import java.lang.System.Logger.Level;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -59,11 +57,6 @@ class ObserverManager {

private static final Map<ExecutorService, SupplierInfo> EXECUTOR_SERVICES = new ConcurrentHashMap<>();

// Defer building list until use to avoid loading problems if this JDK does not support ThreadPerTaskExecutor.
private static final LazyValue<List<ExecutorServiceSupplierObserver.MethodInvocation>> METRICS_RELATED_METHOD_INVOCATIONS =
LazyValue.create(() -> List.of(
MethodInvocationImpl.create("Thread count", "thread-count", "threadCount")));

private ObserverManager() {
}

Expand All @@ -73,33 +66,17 @@ private ObserverManager() {
* @param supplier the supplier of {@code ExecutorService} instances
* @param supplierCategory category of the supplier (e.g., scheduled, server)
* @param executorServiceCategory category of executor services the supplier creates (e.g., ad-hoc)
* @param useVirtualThreads whether virtual threads should be used
*/
static void registerSupplier(Supplier<? extends ExecutorService> supplier,
String supplierCategory,
String executorServiceCategory,
boolean useVirtualThreads) {
String executorServiceCategory) {
int supplierIndex = SUPPLIER_CATEGORY_NEXT_INDEX_VALUES.computeIfAbsent(supplierCategory, key -> new AtomicInteger())
.getAndIncrement();
SUPPLIERS.computeIfAbsent(supplier,
s -> SupplierInfo.create(s,
executorServiceCategory,
supplierCategory,
supplierIndex,
useVirtualThreads));
}

/**
* Registers a supplier which will never use thread-per-task thread pools.
*
* @param supplier the supplier of {@code ExecutorService} instances
* @param supplierCategory category of the supplier (e.g., server, scheduled)
* @param executorServiceCategory category of thread pools which the supplier provides
*/
static void registerSupplier(Supplier<? extends ExecutorService> supplier,
String supplierCategory,
String executorServiceCategory) {
registerSupplier(supplier, supplierCategory, executorServiceCategory, false);
s -> SupplierInfo.create(s,
executorServiceCategory,
supplierCategory,
supplierIndex));
}

/**
Expand Down Expand Up @@ -152,41 +129,31 @@ private static class SupplierInfo {
private final String executorServiceCategory;
private final String supplierCategory;
private final int supplierIndex;
private final boolean useVirtualThreads;
private final AtomicInteger nextThreadPoolIndex = new AtomicInteger(0);
private final List<ExecutorServiceSupplierObserver.SupplierObserverContext> observerContexts;

private static SupplierInfo create(Supplier<? extends ExecutorService> supplier,
String executorServiceCategory,
String supplierCategory,
int supplierIndex,
boolean useVirtualThreads) {
return new SupplierInfo(supplier, supplierCategory, executorServiceCategory, supplierIndex, useVirtualThreads);
int supplierIndex) {
return new SupplierInfo(supplier, supplierCategory, executorServiceCategory, supplierIndex);
}

private SupplierInfo(Supplier<? extends ExecutorService> supplier,
String supplierCategory,
String executorServiceCategory,
int supplierIndex,
boolean useVirtualThreads) {
int supplierIndex) {
this.supplier = supplier;
this.supplierCategory = supplierCategory;
this.executorServiceCategory = executorServiceCategory;
this.supplierIndex = supplierIndex;
this.useVirtualThreads = useVirtualThreads;
observerContexts = collectObserverContexts();
}

private List<ExecutorServiceSupplierObserver.SupplierObserverContext> collectObserverContexts() {
return OBSERVERS.get()
.stream()
.map(observer ->
useVirtualThreads
? observer.registerSupplier(supplier,
supplierIndex,
supplierCategory,
METRICS_RELATED_METHOD_INVOCATIONS.get())
: observer.registerSupplier(supplier,
.map(observer -> observer.registerSupplier(supplier,
supplierIndex,
supplierCategory))

Expand All @@ -206,56 +173,4 @@ void unregisterExecutorService(ExecutorService executorService) {
EXECUTOR_SERVICES.remove(executorService);
}
}

/**
* Encapsulation of information needed to invoke methods on {@code ThreadPerTaskExecutor} and to create metrics from the
* returned values.
*/
private static class MethodInvocationImpl implements ExecutorServiceSupplierObserver.MethodInvocation {
private final String displayName;
private final String description;
private final Method method;
private final Class<?> type;

private static final LazyValue<ExecutorService> VIRTUAL_EXECUTOR_SERVICE = LazyValue
.create(Executors::newVirtualThreadPerTaskExecutor);

static MethodInvocationImpl create(String displayName, String description, String methodName) {
ExecutorService executorService = VIRTUAL_EXECUTOR_SERVICE.get();
Method method = null;
try {
method = executorService.getClass().getDeclaredMethod(methodName);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return new MethodInvocationImpl(displayName, description, method);
}

MethodInvocationImpl(String displayName, String description, Method method) {
this.displayName = displayName;
this.description = description;
this.method = method;
this.type = method.getReturnType();
}

@Override
public String displayName() {
return displayName;
}

@Override
public String description() {
return description;
}

@Override
public Method method() {
return method;
}

@Override
public Class<?> type() {
return type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022 Oracle and/or its affiliates.
* Copyright (c) 2018, 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,11 +29,6 @@ public final class ServerThreadPoolSupplier implements Supplier<ExecutorService>

private static final int MINIMUM_CORES = 2;
private static final int DEFAULT_MIN_THREADS_PER_CORE = 2;
private static final int DEFAULT_MAX_THREADS_PER_CORE = 8;
private static final int DEFAULT_QUEUE_CAPACITY = 8192;
private static final int DEFAULT_GROWTH_THRESHOLD = 256;
private static final int DEFAULT_GROWTH_RATE = 5;

private final ThreadPoolSupplier supplier;

private ServerThreadPoolSupplier(final ThreadPoolSupplier.Builder builder) {
Expand All @@ -57,14 +52,9 @@ public static ThreadPoolSupplier.Builder builder() {

final int cores = Math.max(Runtime.getRuntime().availableProcessors(), MINIMUM_CORES);
final int minPoolSize = DEFAULT_MIN_THREADS_PER_CORE * cores;
final int maxPoolSize = DEFAULT_MAX_THREADS_PER_CORE * cores;

return ThreadPoolSupplier.builder()
.corePoolSize(minPoolSize)
.maxPoolSize(maxPoolSize)
.queueCapacity(DEFAULT_QUEUE_CAPACITY)
.growthThreshold(DEFAULT_GROWTH_THRESHOLD)
.growthRate(DEFAULT_GROWTH_RATE);
.corePoolSize(minPoolSize);
}

/**
Expand Down
Loading

0 comments on commit 21a2b83

Please sign in to comment.