Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolves #3239
Two general issues:
Conflation of default routing rules and service endpoint rules (e.g., metrics endpoint rules)
The earlier refactoring which added
HelidonRestServiceSupport
inservice-common/rest
andHelidonRestCdiExtendion
inservice-common/rest-cdi
failed to account fully for the fact that the service endpoint (such as/metrics
) can be on a different socket from the normal traffic that is to be measured. The original refactoring passed the service endpoint routing rules intoMetricsSupport
which then used that one set of rules both for setting up the/metrics
endpoint and for adding a handler to actually measure the traffic.The result, as observed in the bug, was that only the traffic on the metrics socket was measured and, therefore, reported in the
/metrics
endpoint responses. This worked OK when the endpoint was on the default socket, but not when the endpoint and the regular traffic were on different sockets.The fix: Generalize the earlier refactoring a bit so both the default rules and the possibly-different service endpoint rules are passed into
HelidonRestServiceSupport#postConfigureEndpoint
That'sMetricsSupport#postConfigureEndpoint
in this particular case. Also updateMetricsSupport
to use the different sets of rules correctly in establishing the/metrics
endpoint and in setting up the handler to measure the normal traffic.Note that this fix changes the signature of the public methodHelidonRestServiceSupport#configureEndpoint
. Although users are probably not extending this class themselves, that’s possible so these changes keep the original signature marked as@Deprecated
and add the new signature.Possible to decrement in-flight metrics without incrementing
(This problem has an unrelated cause but I found it in testing the above fix so I'm fixing in this PR because it affects only one class.)
The earlier enhancement to support extended KPI metrics changed
ServerCdiExtension
inmicroprofile/server
so that it would register a handler, early in the request handler chain, to add to each request’s context aKeyPerformanceIndicatorContext.DeferrableRequestContext
. This context allows downstream handlers to distinguish between receipt of a request and the start of processing of the request. Related changes to theJerseySupport
class explicitly recorded the start of processing of the request via theDeferrableRequestContext
.But this did not account for the case, as with service endpoints like metrics, where the downstream handler chain might not include a handler that dealt with the start of processing distinctly from the receipt of the request. The incorrect result is that the extended KPI metrics would decrement the in-flight request measurement (this happens in the handler which is added by
MetricsSupport#configureVendorMetrics
) which had never been incremented by any handler. If you access the/metrics
endpoint several times in a row, you would see the reported in-flight requests values decrease and perhaps become negative.The fix: The
DeferrableRequestContext
now records the “start” time when the request is received and then overwrites it when a handler explicitly marks the start of processing (if that, in fact, occurs). Then, the end-of-processing code checks to see whether the context was ever explicitly marked as started. If not, it mimics a start to update the appropriate metrics before running the end-of-processing logic. This provides as close an approximation as we can to the actual processing time given the absence of a handler that would do better.