gRPC instrumentation fix and refactoring #2067
Merged
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.
What does this PR do?
This PR started as a fix to an issue reported in the forum.
The issue is related to a change we did when tests of gRPC version 1.35 started failing due to duplicated client spans. In order to get rid of the extra span, we excluded
io.grpc.internal.ManagedChannelImpl$RealChannelfrom ourChannelInstrumentation. However, this broke other scenarios, so this PR restores instrumentation of said channel and adds special handling for theio.grpc.internal.DelayedClientCall(added in 1.32) instead. This new client call type is created as a placeholder and starts going through the client call lifecycle, but at some point (different between 1.32 and 1.35) it starts referring to the real client call and delegate invocations to it. The new lifecycle management allows creation of duplicated spans, but whenio.grpc.internal.DelayedClientCalls are used, their corresponding spans replace the ones created for the "real" calls once they are set as the delegate of the placeholder call, and the spans created for the real calls are discarded.In addition, we now use
ensureInstrumentedto instrument client calls, server calls, client listeners and server listeners. By doing that, we can both be very efficient in type matching and still support custom types. While customer client/server calls are sort of edge case, custom listeners are probably more expected. Our tests now include custom client call and client/server listeners.Lastly, I refactored all instrumentations to extract advice methods into separate (inner) classes, so to ensure proper dependencies visibility.
In a separate PR I intend to apply some enhancements to
SpanConcurrentHashMapand then replace all maps withinGrpcHelperwith such.Checklist