My team is maintaining an API management proxy based on jetty-9 AsyncProxyServlet
<jetty.version>9.4.30.v20200611</jetty.version>
Our current goal is to provide SLO monitors based on prometheus metrics
So far we have implemented our counters using a custom AsyncListener
Here is the listener code
@AllArgsConstructor
class AccessLogAsyncListener implements AsyncListener {
private final AccessLogger accessLogger;
@Override
public void onComplete(final AsyncEvent event) {
accessLogger.log(event.getSuppliedRequest(), event.getSuppliedResponse(), ProxyRequestStatus.SUCCESS);
}
@Override
public void onTimeout(final AsyncEvent event) {
accessLogger.log(event.getSuppliedRequest(), event.getSuppliedResponse(), ProxyRequestStatus.TIMEOUT);
}
@Override
public void onError(final AsyncEvent event) {
accessLogger.log(event.getSuppliedRequest(), event.getSuppliedResponse(), ProxyRequestStatus.ERROR);
}
@Override
public void onStartAsync(final AsyncEvent event) {
}
}
A dedicated counter being incremented based on the request status
The listener is added in a servlet filter using the following code
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
if (request.isAsyncStarted()) {
request.getAsyncContext().addListener(accessLogAsyncListener);
} else {
accessLogger.log(request, response, ProxyRequestStatus.UNKNOWN);
}
}
When the workload starts hitting around 2k req / 30s, we get a pretty fair amount of counters being incremented for the UNKNOWN
status (meaning that the request as not been marked as asyncStarted). With 4k req / 30s the ratio is around 13-15%.
My question being: What is the underlying mechanism that makes Jetty decide when to mark or not mark a request as async started ?
My guess is that there is a threshold value defined somewhere that triggers this behaviour to kick in. Can someone give us some insights on the topic ?
As an additional question, what would be the correct way of deducing a status (similar to what is done in the complete, error or timeout callbacks) if the request has not been started async ?
Never mind, I figured it out.
Requests not marked as async are actually requests that did not pass the filter chain for a legitimate reason (wrong or missing API key)
Passed the filter chain all requests are effectively handled asynchronously.