Skip to content

Upgrade gRPC-C++ to 1.28.0 #4312

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

Merged
merged 18 commits into from
Apr 22, 2020
Merged

Upgrade gRPC-C++ to 1.28.0 #4312

merged 18 commits into from
Apr 22, 2020

Conversation

wilhuff
Copy link
Contributor

@wilhuff wilhuff commented Nov 14, 2019

This unblocks nanopb changes proposed in #4264.

This upgrades everything in the gRPC constellation of dependencies to match gRPC at 1.28:

  • gRPC to 1.28.0 (note that gRPC 1.28.1, while released, is a fix for just the python binding and there's no gRPC-C++ CocoaPod at that version)
  • Abseil to 20200225 (as of gRPC 1.27 this is now a gRPC dependency too; there's a later patch but gRPC doesn't use it yet)
  • Protobuf C++ to 3.11.4 (only used for testing in Firestore)
  • C-Ares to 1.15.0
  • BoringSSL to match (no change between gRPC 1.27.0 and 1.28.0)

This is best reviewed as individual commits, largely ignoring 243bef4, which is a commit of generated code to keep our CocoaPod-based build simple.

Copy link
Member

@paulb777 paulb777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please resolve the testCanWriteVeryLargeBatches integration test failures

@wilhuff wilhuff force-pushed the wilhuff/upgrade-grpc branch from 90998a3 to 4efb5c4 Compare April 16, 2020 00:41
@wilhuff wilhuff changed the base branch from master to wilhuff/fix-unused April 16, 2020 00:41
wilhuff added 6 commits April 15, 2020 17:43
In addition to the version change, this comes with some other changes:

  * gRPC now depends upon Abseil, so we no longer directly include
    abseil-cpp for ourselves.
  * gRPC's CMake system now allows all interesting dependencies to
    specify their location via a ROOT_DIR variable (e.g.
    ABSL_ROOT_DIR). Use these to move sources outside the gRPC source
    tree, removing the need for a separate grpc-download target. This
    fixes the problem where each gRPC upgrade would wipe out its
    dependencies.

This unblocks nanopb changes proposed in #4264.
Use a non-empty hostname for gRPC testing

gRPC doesn't validate this but the new Abseil version asserts that gRPC
accesses past the end of the string when passed an empty hostname.
@wilhuff wilhuff force-pushed the wilhuff/upgrade-grpc branch from 4efb5c4 to 403264b Compare April 16, 2020 00:43
@wilhuff wilhuff changed the title Upgrade gRPC-C++ to 1.25.0 Upgrade gRPC-C++ to 1.28.0 Apr 16, 2020
@wilhuff wilhuff requested a review from var-const April 16, 2020 00:51
@wilhuff wilhuff removed their assignment Apr 16, 2020
@wilhuff
Copy link
Contributor Author

wilhuff commented Apr 16, 2020

Note that I've rebased this change onto current master and updated the versions this tackles. So far this hasn't run into any of the issues I saw with gRPC 1.25.0.

@wilhuff
Copy link
Contributor Author

wilhuff commented Apr 16, 2020

Argh. I've been re-running the integration tests repeatedly and can still see the occasional flake. This isn't safe to merge as-is :-(.

Copy link
Contributor

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM (didn't look at the generated proto code too closely).

@var-const var-const assigned wilhuff and unassigned var-const Apr 16, 2020
@wilhuff wilhuff changed the base branch from wilhuff/fix-unused to master April 20, 2020 21:58
Disable CFStream-based transport on Apple platforms due to b/133182964,
wherein CFStream will occasionally fail to raise a has-bytes-available
events, causing Firestore to appear to hang.

Without this, about 1 in 100 Firestore integration tests will hang after
making a request.
@wilhuff
Copy link
Contributor Author

wilhuff commented Apr 22, 2020

PTAL, 5e74ae5 represents a significant change.

@wilhuff wilhuff assigned var-const and unassigned wilhuff Apr 22, 2020
// CFStream will occasionally fail to raise a has-bytes-available events,
// causing Firestore to appear to hang.
//
// Use a constructor of a globally scoped object to set the `grpc_cfstream`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ingenious, though I'd like to double-check if it's necessary. Does the gRPC team recommend doing it this way? Is there perhaps some well-defined point better suited for setenv calls? Note that this is mostly me playing the devil's advocate -- I'm pretty sure this is a good implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gRPC team didn't have any more advice than "set grpc_cfstream=0". Here's their official documentation: https://github.com/grpc/grpc/blob/master/src/objective-c/README-CFSTREAM.md

In general, the best way to handle calls to setenv is to put them at the top of your main function. This avoids data races that are otherwise inherent in multiple threads setting and getting environment variables concurrently. As a library author we don't really control main so it's kind of a crapshoot as to whether or not we'll make the call before anyone else uses gRPC.

Indeed, my initial implementation was to put this in the GrpcConnection constructor:

#if __APPLE__
  static std::once_flag grpc_cfstream_disabled;

  std::call_once(grpc_cfstream_disabled, [] {
    setenv("grpc_cfstream", "0", 1);
  });
#endif  // __APPLE__

However, this didn't work. In gRPC-C++, the call to grpc_init happens implicitly and it seems to happen for essentially any API call. Other calls must have happened earlier and prevented the variable from being read.

I looked for other places insert this to make this earlier (for example, making a static Datastore::InitGrpc and calling it from the api::Firestore constructor (or similar) but this causes the problem that every different way we construct Firestore or FirestoreClient instances has to be adjusted or it will be subject to flakes if we forget. I didn't want to take the chance that we might forget to make this call so this approach seemed better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for elaborating on the rationale. I think it's a great solution.

Copy link
Contributor

@var-const var-const left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations on finding the root cause!

@var-const var-const assigned wilhuff and unassigned var-const Apr 22, 2020
@wilhuff wilhuff merged commit 1df5574 into master Apr 22, 2020
@wilhuff wilhuff deleted the wilhuff/upgrade-grpc branch April 22, 2020 21:03
ryanwilson pushed a commit that referenced this pull request Apr 24, 2020
This unblocks nanopb changes proposed in #4264.

This upgrades everything in the gRPC constellation of dependencies to match gRPC at 1.28:

  * gRPC to 1.28.0 (note that gRPC 1.28.1, while released, is a fix for just the python binding and there's no gRPC-C++ CocoaPod at that version)
  * Abseil to 20200225 (as of gRPC 1.27 this is now a gRPC dependency too; there's a later patch but gRPC doesn't use it yet)
  * Protobuf C++ to 3.11.4 (only used for testing in Firestore)
  * C-Ares to 1.15.0
  * BoringSSL to match (no change between gRPC 1.27.0 and 1.28.0)

Also, this disables CFStream-based transport on Apple platforms. This works around b/133182964, wherein CFStream will occasionally fail to raise a has-bytes-available events, causing Firestore to appear to hang.
@firebase firebase locked and limited conversation to collaborators May 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants