Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid crashes in tracing wrappers for streams #14458

Closed
3 tasks
dbolduc opened this issue Jul 10, 2024 · 1 comment · Fixed by #14477
Closed
3 tasks

Avoid crashes in tracing wrappers for streams #14458

dbolduc opened this issue Jul 10, 2024 · 1 comment · Fixed by #14477
Assignees
Labels
good first issue This issue is a good place to started contributing to this repository. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@dbolduc
Copy link
Member

dbolduc commented Jul 10, 2024

Background

This is a similar issue to #13724.

Some of our tracing wrappers can crash. They crash when we try to access server initial metadata (aka "headers"), but the grpc::ClientContext has not been used.

return EndSpan(*std::move(context_), *std::move(span_), std::move(status));

The gRPC team tells us in practice that when one of these streams is started (i.e. Start() has been called and returns true), the grpc::ClientContext will have metadata available.

Testing

For example, the following test will crash at HEAD, but should not.

TEST(AsyncStreamingReadRpcTracing, UnstartedStreamShouldNotExtractMetadata) {
  auto span_catcher = testing_util::InstallSpanCatcher();

  {
    auto mock = std::make_unique<MockStream>();
    auto span = MakeSpan("span");
    auto context = std::make_shared<grpc::ClientContext>();
    TestedStream stream(context, std::move(mock), span);
  }

  auto spans = span_catcher->GetSpans();
  EXPECT_THAT(spans, ElementsAre(SpanNamed("span")));
}

We will also want a test like:

TEST(AsyncStreamingReadRpcTracing, StartedStreamShouldExtractMetadata) { ... }

To run the unit tests for AsyncStreamingReadRpcTracing with Bazel, we can say:

bazel test --test_output=all //google/cloud:internal_async_streaming_read_rpc_tracing_test

Solution?

One fix is to keep using the EndSpan(grpc::ClientContext, ...) when the stream has been started successfully...

But use the EndSpan() overload without a grpc::ClientContext when the stream was not started successfully.

future<T> EndSpan(
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span,
future<T> fut) {

Tasks

The following classes all have the same problem:

@dbolduc dbolduc added type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. priority: p2 Moderately-important priority. Fix may not be included in next release. good first issue This issue is a good place to started contributing to this repository. labels Jul 10, 2024
@coryan
Copy link
Contributor

coryan commented Jul 15, 2024

FWIW, this is stopping me from using tracing with the storage_experimental::AsyncClient. I think the thing also crashes if the request is cancelled too early.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue This issue is a good place to started contributing to this repository. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants