Avoid direct access to executor to record worker pool metrics
Closes #22742
This commit is contained in:
parent
798c6a5aaa
commit
8c5818a46e
3 changed files with 32 additions and 29 deletions
|
@ -29,7 +29,6 @@ import io.quarkus.deployment.annotations.Produce;
|
||||||
import io.quarkus.deployment.annotations.Record;
|
import io.quarkus.deployment.annotations.Record;
|
||||||
import io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem;
|
import io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem;
|
||||||
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
|
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
|
||||||
import io.quarkus.deployment.builditem.ExecutorBuildItem;
|
|
||||||
import io.quarkus.deployment.builditem.FeatureBuildItem;
|
import io.quarkus.deployment.builditem.FeatureBuildItem;
|
||||||
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
|
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
|
||||||
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
|
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
|
||||||
|
@ -567,7 +566,7 @@ class KeycloakProcessor {
|
||||||
|
|
||||||
@Record(ExecutionTime.RUNTIME_INIT)
|
@Record(ExecutionTime.RUNTIME_INIT)
|
||||||
@BuildStep
|
@BuildStep
|
||||||
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder, ExecutorBuildItem executor, NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {
|
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder, NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {
|
||||||
|
|
||||||
List<String> ignoredPaths = new ArrayList<>();
|
List<String> ignoredPaths = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -583,7 +582,7 @@ class KeycloakProcessor {
|
||||||
.orElse(QUARKUS_DEFAULT_METRICS_PATH)));
|
.orElse(QUARKUS_DEFAULT_METRICS_PATH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
filters.produce(new FilterBuildItem(recorder.createRequestFilter(ignoredPaths, executor.getExecutorProxy()),FilterBuildItem.AUTHORIZATION - 10));
|
filters.produce(new FilterBuildItem(recorder.createRequestFilter(ignoredPaths),FilterBuildItem.AUTHORIZATION - 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@BuildStep
|
@BuildStep
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.keycloak.quarkus.runtime;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
@ -142,8 +141,8 @@ public class KeycloakRecorder {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuarkusRequestFilter createRequestFilter(List<String> ignoredPaths, ExecutorService executor) {
|
public QuarkusRequestFilter createRequestFilter(List<String> ignoredPaths) {
|
||||||
return new QuarkusRequestFilter(createIgnoredHttpPathsPredicate(ignoredPaths), executor);
|
return new QuarkusRequestFilter(createIgnoredHttpPathsPredicate(ignoredPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate<RoutingContext> createIgnoredHttpPathsPredicate(List<String> ignoredPaths) {
|
private Predicate<RoutingContext> createIgnoredHttpPathsPredicate(List<String> ignoredPaths) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.integration.web;
|
package org.keycloak.quarkus.runtime.integration.web;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -53,17 +52,14 @@ public class QuarkusRequestFilter implements Handler<RoutingContext>, Transactio
|
||||||
|
|
||||||
private final Logger logger = Logger.getLogger(QuarkusRequestFilter.class);
|
private final Logger logger = Logger.getLogger(QuarkusRequestFilter.class);
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final Predicate<RoutingContext> contextFilter;
|
||||||
|
|
||||||
private Predicate<RoutingContext> contextFilter;
|
|
||||||
|
|
||||||
public QuarkusRequestFilter() {
|
public QuarkusRequestFilter() {
|
||||||
this(null, null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuarkusRequestFilter(Predicate<RoutingContext> contextFilter, ExecutorService executor) {
|
public QuarkusRequestFilter(Predicate<RoutingContext> contextFilter) {
|
||||||
this.contextFilter = contextFilter;
|
this.contextFilter = contextFilter;
|
||||||
this.executor = executor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LongAdder rejectedRequests = new LongAdder();
|
private final LongAdder rejectedRequests = new LongAdder();
|
||||||
|
@ -78,7 +74,18 @@ public class QuarkusRequestFilter implements Handler<RoutingContext>, Transactio
|
||||||
// our code should always be run as blocking until we don't provide a better support for running non-blocking code
|
// our code should always be run as blocking until we don't provide a better support for running non-blocking code
|
||||||
// in the event loop
|
// in the event loop
|
||||||
try {
|
try {
|
||||||
executor.execute(createBlockingHandler(context));
|
// When running in Quarkus dev mode, this will run on Vert.x default worker pool.
|
||||||
|
// When running in Quarkus production mode, this will run on the Quarkus executor pool.
|
||||||
|
// It should not call the Quarkus executor directly, as this prevents metrics for `worker_pool_*` to be collected.
|
||||||
|
// See https://github.com/quarkusio/quarkus/issues/34998 for a discussion.
|
||||||
|
context.vertx().executeBlocking(ctx -> {
|
||||||
|
try {
|
||||||
|
runBlockingCode(context);
|
||||||
|
ctx.complete();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
ctx.fail(ex);
|
||||||
|
}
|
||||||
|
}, false, null);
|
||||||
if (loadSheddingActive) {
|
if (loadSheddingActive) {
|
||||||
synchronized (rejectedRequests) {
|
synchronized (rejectedRequests) {
|
||||||
if (loadSheddingActive) {
|
if (loadSheddingActive) {
|
||||||
|
@ -107,22 +114,20 @@ public class QuarkusRequestFilter implements Handler<RoutingContext>, Transactio
|
||||||
return contextFilter != null && contextFilter.test(context);
|
return contextFilter != null && contextFilter.test(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable createBlockingHandler(RoutingContext context) {
|
private void runBlockingCode(RoutingContext context) {
|
||||||
return () -> {
|
KeycloakSession session = configureContextualData(context);
|
||||||
KeycloakSession session = configureContextualData(context);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.next();
|
context.next();
|
||||||
} catch (Throwable cause) {
|
} catch (Throwable cause) {
|
||||||
// re-throw so that the any exception is handled from parent
|
// re-throw so that the any exception is handled from parent
|
||||||
throw new RuntimeException(cause);
|
throw new RuntimeException(cause);
|
||||||
} finally {
|
} finally {
|
||||||
// force closing the session if not already closed
|
// force closing the session if not already closed
|
||||||
// under some circumstances resteasy might not be invoked like when no route is found for a particular path
|
// under some circumstances resteasy might not be invoked like when no route is found for a particular path
|
||||||
// in this case context is set with status code 404, and we need to close the session
|
// in this case context is set with status code 404, and we need to close the session
|
||||||
close(session);
|
close(session);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeycloakSession configureContextualData(RoutingContext context) {
|
private KeycloakSession configureContextualData(RoutingContext context) {
|
||||||
|
|
Loading…
Reference in a new issue