feat(gax): o11y tracer helper updates - #9269
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates constructSettings to include internalMethodName in otherArgs when telemetry is enabled, and refactors traceAttempt in TracerHelper.ts to be synchronous. The refactored traceAttempt now dynamically manages OpenTelemetry span lifecycles based on whether the traced operation returns a Promise, an EventEmitter (stream), or a synchronous value. Comprehensive unit tests have been added to verify these behaviors. There are no review comments, so I have no feedback to provide.
5c87d1a to
a32c4c4
Compare
a4484e3 to
f1ce37e
Compare
8c7ca7f to
739630a
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors traceAttempt in TracerHelper.ts to support asynchronous span lifecycle management for both promise-based and stream-based operations, introducing helper functions handlePromise and handleStream along with comprehensive unit tests. The review feedback highlights two important improvements: first, to avoid deferring span completion to a microtask for synchronous operations, we should check if the result is a thenable and end the span synchronously if it is not; second, to prevent potential memory leaks, we should clean up the event listeners registered on the stream in handleStream once the span has ended.
060ce94 to
c717da1
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces asynchronous span lifecycle management for both Promise-based and Stream-based operations in TracerHelper.ts, along with comprehensive unit tests. However, a critical issue was identified where spans are leaked (never ended) if the traced function returns a synchronous value or an unsupported type. To resolve this, an else block should be added to immediately end the span for synchronous or unsupported return types.
dabd501 to
ae2d6f6
Compare
danieljbruce
left a comment
There was a problem hiding this comment.
Left a couple comments. Overall, I think I need to understand the problem and architecture more broadly to understand how traceAttempt and traceHelper.ts are used.
| const cleanup = () => { | ||
| stream.removeListener('error', onError); | ||
| stream.removeListener('end', onEnd); | ||
| stream.removeListener('close', onClose); |
There was a problem hiding this comment.
I don't know too much about how this code fits in with the broader architecture, but one thought I had is if we remove the listeners here which I see intends to remove the listeners applied on the stream.on('error', onError) lines of code then it is going to remove other listeners as well that we need?
I remember google-gax applies a lot of error listeners in its middleware to handle retries and other such tasks.
There was a problem hiding this comment.
I double checked, and I confirmed taht removeListener() removes only the reference for that specific callback that's used. In contrast, removeAllListeners() cleans up all of the listeners and would affect the middleware listeners.
| @@ -163,5 +172,572 @@ describe('TracerHelper', () => { | |||
| assert.strictEqual(spans.length, 1); | |||
| assert.strictEqual(spans[0].attributes['gcp.method.type'], 'http'); | |||
| }); | |||
There was a problem hiding this comment.
Could it be in scope to test retries here? I know they get complex with the streaming calls.
There was a problem hiding this comment.
Good point, thank you! I've added tests for retries in streams
d66cee1 to
f2218ab
Compare
danieljbruce
left a comment
There was a problem hiding this comment.
Ok. The code LGTM. I see how the traceAttempt is used as a wrapper with invokeCall. Maybe consider inlining traceAttempt into createApiCall and then refactoring pieces of it out to eliminate the need to pass a fn: () => T parameter, but that shouldn't block. Maybe just consider it as a backlog item.
The broader thing that might just be good to check is to run the google-gax tests. After the monorepo migration, I don't think they run in the CI pipeline anymore. I'll send a link on chat for how to run the gax tests. Probably would be good to run the gax tests before merging.
…nt premature span endings
f2218ab to
8b2e8a9
Compare
Updates
traceAttemptinTracerHelper.tsto manage span lifecycles across either Promises or streaming RPCs without closing spans prematurely.traceAttempt()function call to account for Promises or Streams returned from GAXNote: confirmed that the
google-gaxtest suite passes withnpm run test-application