use of io.perfmark.TaskCloseable in project zuul by Netflix.
the class BaseZuulFilterRunner method filter.
protected final O filter(final ZuulFilter<I, O> filter, final I inMesg) {
final long startTime = System.nanoTime();
final ZuulMessage snapshot = inMesg.getContext().debugRouting() ? inMesg.clone() : null;
FilterChainResumer resumer = null;
try (TaskCloseable ignored = traceTask(filter, f -> f.filterName() + ".filter")) {
addPerfMarkTags(inMesg);
ExecutionStatus filterRunStatus = null;
if (filter.filterType() == INBOUND && inMesg.getContext().shouldSendErrorResponse()) {
// Pass request down the pipeline, all the way to error endpoint if error response needs to be generated
filterRunStatus = SKIPPED;
}
;
try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".shouldSkipFilter")) {
if (shouldSkipFilter(inMesg, filter)) {
filterRunStatus = SKIPPED;
}
}
if (filter.isDisabled()) {
filterRunStatus = DISABLED;
}
if (filterRunStatus != null) {
recordFilterCompletion(filterRunStatus, filter, startTime, inMesg, snapshot);
return filter.getDefaultOutput(inMesg);
}
if (!isMessageBodyReadyForFilter(filter, inMesg)) {
setFilterAwaitingBody(inMesg, true);
logger.debug("Filter {} waiting for body, UUID {}", filter.filterName(), inMesg.getContext().getUUID());
// wait for whole body to be buffered
return null;
}
setFilterAwaitingBody(inMesg, false);
if (snapshot != null) {
Debug.addRoutingDebug(inMesg.getContext(), "Filter " + filter.filterType().toString() + " " + filter.filterOrder() + " " + filter.filterName());
}
// run body contents accumulated so far through this filter
inMesg.runBufferedBodyContentThroughFilter(filter);
if (filter.getSyncType() == FilterSyncType.SYNC) {
final SyncZuulFilter<I, O> syncFilter = (SyncZuulFilter) filter;
final O outMesg;
try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".apply")) {
addPerfMarkTags(inMesg);
outMesg = syncFilter.apply(inMesg);
}
recordFilterCompletion(SUCCESS, filter, startTime, inMesg, snapshot);
return (outMesg != null) ? outMesg : filter.getDefaultOutput(inMesg);
}
// async filter
try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".applyAsync")) {
final Link nettyToSchedulerLink = linkOut();
filter.incrementConcurrency();
resumer = new FilterChainResumer(inMesg, filter, snapshot, startTime);
filter.applyAsync(inMesg).doOnSubscribe(() -> {
try (TaskCloseable ignored3 = traceTask(filter, f -> f.filterName() + ".onSubscribeAsync")) {
linkIn(nettyToSchedulerLink);
}
}).doOnNext(resumer.onNextStarted(nettyToSchedulerLink)).doOnError(resumer.onErrorStarted(nettyToSchedulerLink)).doOnCompleted(resumer.onCompletedStarted(nettyToSchedulerLink)).observeOn(Schedulers.from(getChannelHandlerContext(inMesg).executor())).doOnUnsubscribe(resumer::decrementConcurrency).subscribe(resumer);
}
// wait for the async filter to finish
return null;
} catch (Throwable t) {
if (resumer != null) {
resumer.decrementConcurrency();
}
final O outMesg = handleFilterException(inMesg, filter, t);
outMesg.finishBufferedBodyIfIncomplete();
recordFilterCompletion(FAILED, filter, startTime, inMesg, snapshot);
return outMesg;
}
}
use of io.perfmark.TaskCloseable in project zuul by Netflix.
the class BaseZuulFilterRunner method invokeNextStage.
protected final void invokeNextStage(final O zuulMesg) {
if (nextStage != null) {
try (TaskCloseable ignored = traceTask(this, s -> s.getClass().getSimpleName() + ".invokeNextStage")) {
addPerfMarkTags(zuulMesg);
nextStage.filter(zuulMesg);
}
} else {
// Next stage is Netty channel handler
try (TaskCloseable ignored = traceTask(this, s -> s.getClass().getSimpleName() + ".fireChannelRead")) {
addPerfMarkTags(zuulMesg);
getChannelHandlerContext(zuulMesg).fireChannelRead(zuulMesg);
}
}
}
use of io.perfmark.TaskCloseable in project zuul by Netflix.
the class ZuulEndPointRunner method filter.
@Override
public void filter(final HttpRequestMessage zuulReq, final HttpContent chunk) {
if (zuulReq.getContext().isCancelled()) {
chunk.release();
return;
}
String endpointName = "-";
try (TaskCloseable ignored = PerfMark.traceTask(this, s -> s.getClass().getSimpleName() + ".filterChunk")) {
addPerfMarkTags(zuulReq);
ZuulFilter<HttpRequestMessage, HttpResponseMessage> endpoint = Preconditions.checkNotNull(getEndpoint(zuulReq), "endpoint");
endpointName = endpoint.filterName();
final HttpContent newChunk = endpoint.processContentChunk(zuulReq, chunk);
if (newChunk != null) {
// Endpoints do not directly forward content chunks to next stage in the filter chain.
zuulReq.bufferBodyContents(newChunk);
// deallocate original chunk if necessary
if (newChunk != chunk) {
chunk.release();
}
if (isFilterAwaitingBody(zuulReq) && zuulReq.hasCompleteBody() && !(endpoint instanceof ProxyEndpoint)) {
// whole body has arrived, resume filter chain
invokeNextStage(filter(endpoint, zuulReq));
}
}
} catch (Exception ex) {
handleException(zuulReq, endpointName, ex);
}
}
use of io.perfmark.TaskCloseable in project zuul by Netflix.
the class ZuulFilterChainRunner method filter.
@Override
public void filter(T inMesg, HttpContent chunk) {
String filterName = "-";
try (TaskCloseable ignored = PerfMark.traceTask(this, s -> s.getClass().getSimpleName() + ".filterChunk")) {
addPerfMarkTags(inMesg);
Preconditions.checkNotNull(inMesg, "input message");
final AtomicInteger runningFilterIdx = getRunningFilterIndex(inMesg);
final int limit = runningFilterIdx.get();
for (int i = 0; i < limit; i++) {
final ZuulFilter<T, T> filter = filters[i];
filterName = filter.filterName();
if ((!filter.isDisabled()) && (!shouldSkipFilter(inMesg, filter))) {
final HttpContent newChunk = filter.processContentChunk(inMesg, chunk);
if (newChunk == null) {
// Filter wants to break the chain and stop propagating this chunk any further
return;
}
// deallocate original chunk if necessary
if ((newChunk != chunk) && (chunk.refCnt() > 0)) {
chunk.release(chunk.refCnt());
}
chunk = newChunk;
}
}
if (limit >= filters.length) {
// Filter chain has run to end, pass down the channel pipeline
invokeNextStage(inMesg, chunk);
} else {
inMesg.bufferBodyContents(chunk);
boolean isAwaitingBody = isFilterAwaitingBody(inMesg);
// Record passport states for start and end of buffering bodies.
if (isAwaitingBody) {
CurrentPassport passport = CurrentPassport.fromSessionContext(inMesg.getContext());
if (inMesg.hasCompleteBody()) {
if (inMesg instanceof HttpRequestMessage) {
passport.addIfNotAlready(PassportState.FILTERS_INBOUND_BUF_END);
} else if (inMesg instanceof HttpResponseMessage) {
passport.addIfNotAlready(PassportState.FILTERS_OUTBOUND_BUF_END);
}
} else {
if (inMesg instanceof HttpRequestMessage) {
passport.addIfNotAlready(PassportState.FILTERS_INBOUND_BUF_START);
} else if (inMesg instanceof HttpResponseMessage) {
passport.addIfNotAlready(PassportState.FILTERS_OUTBOUND_BUF_START);
}
}
}
if (isAwaitingBody && inMesg.hasCompleteBody()) {
// whole body has arrived, resume filter chain
runFilters(inMesg, runningFilterIdx);
}
}
} catch (Exception ex) {
handleException(inMesg, filterName, ex);
}
}
use of io.perfmark.TaskCloseable in project zuul by Netflix.
the class ProxyEndpoint method responseFromOrigin.
public void responseFromOrigin(final HttpResponse originResponse) {
try (TaskCloseable ignore = PerfMark.traceTask("ProxyEndpoint.responseFromOrigin")) {
PerfMark.attachTag("uuid", zuulRequest, r -> r.getContext().getUUID());
PerfMark.attachTag("path", zuulRequest, HttpRequestInfo::getPath);
methodBinding.bind(() -> processResponseFromOrigin(originResponse));
} catch (Exception ex) {
unlinkFromOrigin();
LOG.error("Error in responseFromOrigin", ex);
channelCtx.fireExceptionCaught(ex);
}
}
Aggregations