Skip to content

Commit

Permalink
Merge pull request quarkusio#18912 from Sanne/VertxTCCLReset3
Browse files Browse the repository at this point in the history
Reset the current context Classloader on the threads of the Vertx blocking executor pool
  • Loading branch information
stuartwdouglas authored Jul 22, 2021
2 parents 2a1602b + 0e412f1 commit 5cf94dc
Showing 1 changed file with 34 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import static io.quarkus.vertx.core.runtime.SSLConfigHelper.configurePfxTrustOptions;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -25,6 +27,7 @@

import org.jboss.logging.Logger;
import org.jboss.threads.ContextHandler;
import org.jboss.threads.EnhancedQueueExecutor;
import org.wildfly.common.cpu.ProcessorInfo;

import io.netty.channel.EventLoopGroup;
Expand All @@ -41,7 +44,6 @@
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.dns.AddressResolverOptions;
Expand All @@ -53,6 +55,7 @@
import io.vertx.core.impl.VertxBuilder;
import io.vertx.core.impl.VertxImpl;
import io.vertx.core.impl.VertxThread;
import io.vertx.core.impl.WorkerPool;
import io.vertx.core.spi.VertxThreadFactory;
import io.vertx.core.spi.resolver.ResolverProvider;

Expand Down Expand Up @@ -129,19 +132,14 @@ public void handle(AsyncResult<Void> event) {
private void tryCleanTccl(Vertx devModeVertx) {
//this is a best effort attempt to clean out the old TCCL from
ClassLoader cl = Thread.currentThread().getContextClassLoader();
for (int i = 0; i < blockingThreadPoolSize; ++i) {
devModeVertx.executeBlocking(new Handler<Promise<Object>>() {
@Override
public void handle(Promise<Object> event) {
Thread.currentThread().setContextClassLoader(cl);
try {
Thread.sleep(50);
} catch (InterruptedException e) {

}
}
}, null);
EnhancedQueueExecutor executor = extractExecutor(devModeVertx);

final Thread[] runningThreads = executor.getRunningThreads();
for (Thread t : runningThreads) {
t.setContextClassLoader(cl);
}

EventLoopGroup group = ((VertxImpl) devModeVertx).getEventLoopGroup();
for (EventExecutor i : group) {
i.execute(new Runnable() {
Expand All @@ -156,6 +154,30 @@ public void run() {

}

/**
* Extract the JBoss Threads EnhancedQueueExecutor from the Vertx instance
* this is messy as it needs to use reflection until Vertx can expose it.
*/
private EnhancedQueueExecutor extractExecutor(Vertx devModeVertx) {
final ContextInternal ctx = (ContextInternal) devModeVertx.getOrCreateContext();
final WorkerPool workerPool = ctx.workerPool();
final Method executorMethod;
try {
executorMethod = WorkerPool.class.getDeclaredMethod("executor");
executorMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
final Object result;
try {
result = executorMethod.invoke(workerPool);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
EnhancedQueueExecutor executor = (EnhancedQueueExecutor) result;
return executor;
}

public IOThreadDetector detector() {
return new IOThreadDetector() {
@Override
Expand Down

0 comments on commit 5cf94dc

Please sign in to comment.