Quarkus: Как настроить глобальный Custom ThreadPoolExecutor

Я работаю над проектом, в котором контекст и сеанс безопасно управляются ThreadLocal с помощью ThreadPoolExecutor (информация передается из потока в другой внутри ThreadPoolExecutor).

У нас есть:

  1. ThreadPoolExecutor: он реализует поведение методов beforeExecute и afterExecute, чтобы гарантировать, что информация передается из потока в другой, а контекст потока очищается в методе afterExecutre.
  2. ThreadFactory: отвечает за создание настраиваемого потока с именем Thread, в котором хранится информация о сеансе ThreadLocal.
  3. Пользовательский Runnable, используемый в beforeExecute. Эта запускаемая программа использует исходную + другую необходимую информацию (например, сеанс)

Он отлично работает и протестирован в производственном проекте высокого уровня.

Распространение контекста Quarkus работает нормально. Но перенос текущего (производственного) проекта на Quarkus кажется сложным и рискованным.

Итак, как, например, @Provide CustomThreadPool и quarkus могут использовать его в качестве основного ThreadPool вместо пула по умолчанию.


person naddame    schedule 26.10.2020    source источник


Ответы (1)


Версия Quarkus: 1.9.1.Final

Java: 11

Что ж, вы можете настроить исполнителя основной службы Quarkus с помощью свойств конфигурации . Посмотрите все свойства quarkus.thread-pool.*, а затем используйте его как обычный исполнитель службы.

Чтобы внедрить этот пул потоков в свою службу, убедитесь, что вы поддерживаете распространение контекста, добавив следующее расширение ./mvnw quarkus:add-extension -Dextensions="quarkus-smallrye-context-propagation", как вы можете видеть в эта ссылка

Вставить главного исполнителя службы в вашу службу так же просто, как:

@Inject ManagedExecutor exec;

Создание отдельного исполнителя службы - это другой подход (однако вы должны спросить себя: «Что я получаю с отдельным исполнителем?», «Что я ищу?»), Возможно, имеет смысл, я думаю, это зависит от случая. В этом случае вы можете создать свой собственный ManagedExcutor и использовать его, например:


import io.quarkus.runtime.Startup;
import org.eclipse.microprofile.context.ManagedExecutor;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.ws.rs.Produces;

public class Producers {

    private final static int POOL_SIZE = 4; // TODO move on this hardcode properties to a config file
    private final static int POOL_QUEUE_SIZE = 10;

    @Startup // Instanciated at start-time
    @ApplicationScoped // Only one instance for all your app (Singleton)
    @Produces 
    @Named("customServiceExecutor") // tag your instance, because remember that you will have also another ServiceExecutor (the default one)
    ManagedExecutor managedCustomExecutor() {

        System.out.println("customServiceExecutor created (once)!.");

        return ManagedExecutor.builder()
                .maxAsync(POOL_SIZE)
                .maxQueued(POOL_QUEUE_SIZE)
                .build();
    }

}

А потом воспользуемся !:


import io.smallrye.context.api.NamedInstance;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.context.ManagedExecutor;


import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello/")
public class HelloResource {

    @ConfigProperty(name = "org.pjgg.greeting")
    private String greeting;

    @Inject
    @NamedInstance("customServiceExecutor")
    ManagedExecutor delorean;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        System.out.println(java.lang.Thread.activeCount());

        var promise = delorean.supplyAsync(()-> "You will see this in the future !!!");
        promise.thenAccept(System.out::println);
        System.out.println(java.lang.Thread.activeCount());

        return greeting;
    }
}
person Pablo    schedule 31.10.2020
comment
Спасибо за ответ, но я хочу запустить quarkus поверх моего собственного ThreadPoolExecutor. Переопределите что-то вроде io.quarkus.runtime.ExecutorRecorder.setupRunTime, где кажется, что создается исполнитель по умолчанию. - person naddame; 04.11.2020