Merge remote-tracking branch 'origin/master' into ssa_interop_server

pull/34518/head
Richard Belleville 1 year ago
commit a762b27178
  1. 2
      .bazelci/presubmit.yml
  2. 2
      .bazelversion
  3. 23
      .clang-tidy
  4. 4
      .gitattributes
  5. 12
      .github/CODEOWNERS
  6. 2
      .github/ISSUE_TEMPLATE/bug_report_csharp.md
  7. 2
      .github/ISSUE_TEMPLATE/feature_request_csharp.md
  8. 15
      .github/dependabot.yml
  9. 109
      .github/labeler.yml
  10. 19
      .github/workflows/pr-auto-fix.yaml
  11. 32
      .github/workflows/pr-auto-tag-and-check-title.yaml
  12. 19
      .github/workflows/pr-auto-tag.yaml
  13. 73
      .github/workflows/psm-interop.yaml
  14. 5
      .gitignore
  15. 3
      .gitmodules
  16. 881
      BUILD
  17. 3
      BUILDING.md
  18. 9979
      CMakeLists.txt
  19. 137
      CONTRIBUTING_STEPS.md
  20. 6
      MAINTAINERS.md
  21. 2033
      Makefile
  22. 3
      OWNERS
  23. 1866
      Package.swift
  24. 74
      README.md
  25. 24
      Rakefile
  26. 29
      WORKSPACE
  27. 2
      _metadata.py
  28. 5
      bazel/OWNERS
  29. 148
      bazel/experiments.bzl
  30. 4
      bazel/generate_cc.bzl
  31. 4
      bazel/generate_objc.bzl
  32. 2
      bazel/googleapis.BUILD
  33. 84
      bazel/grpc_build_system.bzl
  34. 166
      bazel/grpc_deps.bzl
  35. 6
      bazel/grpc_extra_deps.bzl
  36. 11
      bazel/grpc_python_deps.bzl
  37. 19
      bazel/python_rules.bzl
  38. 4
      bazel/supported_versions.txt
  39. 10
      bazel/test_experiments.bzl
  40. 17
      bazel/update_mirror.sh
  41. 8
      black.toml
  42. 7648
      build_autogenerated.yaml
  43. 2
      build_config.rb
  44. 16
      build_handwritten.yaml
  45. 3
      cmake/OWNERS
  46. 2
      cmake/upb.cmake
  47. 1131
      config.m4
  48. 1405
      config.w32
  49. 2
      doc/PROTOCOL-HTTP2.md
  50. 14
      doc/bazel_support.md
  51. 56
      doc/command_line_tool.md
  52. 31
      doc/core/default_http_proxy_mapper.md
  53. 2
      doc/environment_variables.md
  54. 6
      doc/g_stands_for.md
  55. 16
      doc/grpc_xds_features.md
  56. BIN
      doc/images/img/grpc-assignee.png
  57. BIN
      doc/images/img/grpc-compare-and-pull-request.png
  58. BIN
      doc/images/img/grpc-contributor-type.png
  59. BIN
      doc/images/img/grpc-copybara-commit.png
  60. BIN
      doc/images/img/grpc-create-fork.png
  61. BIN
      doc/images/img/grpc-easycla-authorize.png
  62. BIN
      doc/images/img/grpc-easycla-covered.png
  63. BIN
      doc/images/img/grpc-pr-closed-by-copybara.png
  64. BIN
      doc/images/img/grpc-pull-request-details.png
  65. BIN
      doc/images/img/grpc-review-complete.png
  66. BIN
      doc/images/img/grpc-sign-cla.png
  67. BIN
      doc/images/img/grpc-tests.png
  68. BIN
      doc/images/img/grpc-wait-for-merge.png
  69. 2
      doc/python/server_reflection.md
  70. 2
      doc/python/sphinx/conf.py
  71. 7
      doc/python/sphinx/glossary.rst
  72. 7
      doc/python/sphinx/grpc_observability.rst
  73. 1
      doc/python/sphinx/index.rst
  74. 4
      doc/server-reflection.md
  75. 12
      doc/service_config.md
  76. 6
      doc/statuscodes.md
  77. 2
      doc/xds-test-descriptions.md
  78. 2
      examples/android/helloworld/app/build.gradle
  79. 1
      examples/cpp/cmake/common.cmake
  80. 2
      examples/cpp/csm/Dockerfile.client
  81. 24
      examples/cpp/csm/README.md
  82. 171
      examples/cpp/csm/csm_greeter_client.cc
  83. 2
      examples/cpp/csm/csm_greeter_server.cc
  84. 39
      examples/cpp/deadline/BUILD
  85. 70
      examples/cpp/deadline/CMakeLists.txt
  86. 35
      examples/cpp/deadline/README.md
  87. 106
      examples/cpp/deadline/client.cc
  88. 130
      examples/cpp/deadline/server.cc
  89. 42
      examples/cpp/debugging/BUILD
  90. 132
      examples/cpp/debugging/README.md
  91. 92
      examples/cpp/debugging/crashing_greeter_client.cc
  92. 86
      examples/cpp/debugging/greeter_callback_server_admin.cc
  93. 40
      examples/cpp/generic_api/BUILD
  94. 70
      examples/cpp/generic_api/CMakeLists.txt
  95. 36
      examples/cpp/generic_api/README.md
  96. 112
      examples/cpp/generic_api/greeter_client.cc
  97. 143
      examples/cpp/generic_api/greeter_server.cc
  98. 29
      examples/cpp/orca/BUILD
  99. 46
      examples/cpp/orca/README.md
  100. 101
      examples/cpp/orca/orca_server.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -12,7 +12,7 @@
---
# TODO(yannic): Ideally, we should also enable buildifier and all platforms should test `//...`.
tasks:
ubuntu1804:
ubuntu2004:
build_targets:
- //:all
- //src/proto/...

@ -1 +1 @@
6.3.2
6.4.0

@ -1,15 +1,24 @@
---
# Note on checks are disabled on purpose
#
# - abseil-cleanup-ctad
# Requires C++17 and higher.
#
# - abseil-no-namespace
# https://bugs.llvm.org/show_bug.cgi?id=47947
#
# - bugprone-exception-escape
# https://github.com/llvm/llvm-project/issues/54668 (seems to be fixed in LLVM17)
#
# - bugprone-reserved-identifier
# Some macros need to be defined for portability purpose; e.g. _BSD_SOURCE.
#
# - modernize-redundant-void-arg
# Some source should be strictly C99 and func(void) should be used.
#
# - google-readability-casting
# https://github.com/llvm/llvm-project/issues/57959
#
# Note on checks which will be enabled in future. These are good to have but
# it's not activated yet due to the existing issues with the checks.
# Once those issues are clear, these checks can be enabled later.
@ -23,6 +32,7 @@
# - bugprone-not-null-terminated-result
# - bugprone-signed-char-misuse
# - bugprone-sizeof-expression
# - bugprone-switch-missing-default-case
# - bugprone-too-small-loop-variable
# - bugprone-unchecked-optional-access
# - clang-diagnostic-deprecated-declarations
@ -41,21 +51,27 @@
# - modernize-use-equals-default
# - modernize-use-equals-delete
# - modernize-use-using
# - performance-avoid-endl
# - performance-no-automatic-move
# - performance-no-int-to-ptr
# - performance-noexcept-swap
# - performance-unnecessary-copy-initialization
# - performance-unnecessary-value-param
# - readability-else-after-return
# - readability-implicit-bool-conversion
# - readability-redundant-declaration
# - readability-redundant-string-cstr
#
Checks: '-*,
abseil-*,
-abseil-cleanup-ctad,
-abseil-no-namespace,
bugprone-*,
-bugprone-assignment-in-if-condition,
-bugprone-branch-clone,
-bugprone-easily-swappable-parameters,
-bugprone-empty-catch,
-bugprone-exception-escape,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-infinite-loop,
-bugprone-narrowing-conversions,
@ -63,16 +79,21 @@ Checks: '-*,
-bugprone-reserved-identifier,
-bugprone-signed-char-misuse,
-bugprone-sizeof-expression,
-bugprone-switch-missing-default-case,
-bugprone-too-small-loop-variable,
-bugprone-unchecked-optional-access,
google-*,
-google-readability-casting,
-google-runtime-int,
-google-runtime-references,
performance-*,
-performance-avoid-endl,
-performance-no-automatic-move,
-performance-no-int-to-ptr,
-performance-noexcept-swap,
-performance-unnecessary-copy-initialization,
-performance-unnecessary-value-param,
clang-diagnostic-deprecated-declarations,
clang-diagnostic-deprecated-register,
clang-diagnostic-expansion-to-defined,
clang-diagnostic-ignored-attributes,
@ -120,7 +141,7 @@ Checks: '-*,
readability-redundant-control-flow,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
-readability-redundant-string-cstr,
readability-redundant-string-init,
readability-simplify-boolean-expr,
readability-static-definition-in-anonymous-namespace,

4
.gitattributes vendored

@ -1,5 +1,5 @@
src/core/ext/upb-generated/** linguist-generated=true
src/core/ext/upbdefs-generated/** linguist-generated=true
src/core/ext/upb-gen/** linguist-generated=true
src/core/ext/upbdefs-gen/** linguist-generated=true
Makefile linguist-generated=true
BUILD.gn linguist-generated=true
CMakeLists.txt linguist-generated=true

@ -1,11 +1,11 @@
# Auto-generated by the tools/mkowners/mkowners.py tool
# Uses OWNERS files in different modules throughout the
# repository as the source of truth for module ownership.
/**/OWNERS @markdroth @a11r
/bazel/** @jtattermusch @veblush @gnossen
/cmake/** @jtattermusch @apolcyn
/bazel/** @veblush @gnossen
/bazel/experiments.yaml
/cmake/** @veblush @apolcyn
/src/core/ext/filters/client_channel/** @markdroth
/src/core/ext/transport/chttp2/transport/** @ctiller
/src/core/ext/xds/** @markdroth
/src/core/lib/resolver/** @markdroth
/src/core/lib/service_config/** @markdroth
/tools/dockerfile/** @jtattermusch @apolcyn
/tools/dockerfile/** @drfloob @apolcyn @gnossen
/tools/run_tests/xds_k8s_test_driver/** @sergiitk @XuanWang-Amos @gnossen

@ -2,7 +2,7 @@
name: Report a gRPC C# bug
about: Create a report to help us improve
labels: kind/bug, priority/P2, lang/C#
assignees: jtattermusch
assignees: apolcyn
---

@ -2,7 +2,7 @@
name: Request a gRPC C# feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2, lang/C#
assignees: jtattermusch
assignees: apolcyn
---

@ -0,0 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"

@ -1,60 +1,65 @@
lang/core:
- src/abseil-cpp/**
- src/boringssl/**
- src/c-ares/**
- src/core/**
- src/proto/**
- src/re2/**
- src/upb/**
- src/zlib/**
- include/grpc/**
- test/core/**
- tools/codegen/core/**
- changed-files:
- any-glob-to-any-file:
- src/abseil-cpp/**
- src/boringssl/**
- src/c-ares/**
- src/core/**
- src/proto/**
- src/re2/**
- src/upb/**
- src/zlib/**
- include/grpc/**
- test/core/**
- tools/codegen/core/**
lang/c++:
- examples/cpp/**
- src/cpp/**
- include/grpc++/**
- include/grpcpp/**
- test/cpp/**
- changed-files:
- any-glob-to-any-file:
- examples/cpp/**
- src/cpp/**
- include/grpc++/**
- include/grpcpp/**
- test/cpp/**
area/infra:
- .github/**
- changed-files:
- any-glob-to-any-file:
- .github/**
lang/node:
- examples/node/**
- src/compiler/node*
- changed-files:
- any-glob-to-any-file:
- examples/node/**
- src/compiler/node*
lang/ObjC:
- examples/objective-c/**
- src/compiler/objective_c*
- src/objective-c/**
- changed-files:
- any-glob-to-any-file:
- examples/objective-c/**
- src/compiler/objective_c*
- src/objective-c/**
lang/php:
- examples/php/**
- src/compiler/php*
- src/php/**
- changed-files:
- any-glob-to-any-file:
- examples/php/**
- src/compiler/php*
- src/php/**
lang/python:
- bazel/python_rules.bzl
- examples/python/**
- requirements.bazel.txt
- src/compiler/python*
- any:
- src/python/**
- "!src/python/grpcio/grpc_core_dependencies.py"
- changed-files:
- any-glob-to-any-file:
- bazel/python_rules.bzl
- examples/python/**
- requirements.bazel.txt
- src/compiler/python*
- all-globs-to-any-file:
- src/python/**
- '!src/python/grpcio/grpc_core_dependencies.py'
- '!src/python/grpcio_observability/observability_lib_deps.py'
lang/ruby:
- examples/ruby/**
- src/compiler/ruby*
- src/ruby/**
"lang/C#":
- src/compiler/csharp*
- src/csharp/**
"disposition/Needs Internal Changes":
- src/core/lib/event_engine/windows/**
- src/core/lib/gpr/windows/**
- src/core/lib/gprpp/windows/**
- test/core/event_engine/windows/**
- changed-files:
- any-glob-to-any-file:
- examples/ruby/**
- src/compiler/ruby*
- src/ruby/**
'lang/C#':
- changed-files:
- any-glob-to-any-file:
- src/compiler/csharp*
- src/csharp/**

@ -12,17 +12,17 @@ jobs:
steps:
# Cache bazel build
- name: Get current time
uses: srfrnk/current-time@master
uses: srfrnk/current-time@5a4163ad035ccd9a407ec9e519c3b6ba1b633d1e # v1.1.0
id: current-time
with:
format: YYYYWW
- name: Get current time
uses: srfrnk/current-time@master
uses: srfrnk/current-time@5a4163ad035ccd9a407ec9e519c3b6ba1b633d1e # v1.1.0
id: current-time-with-day
with:
format: YYYYWWd
- name: Cache bazel
uses: actions/cache@v3
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
env:
cache-name: bazel-cache
with:
@ -38,18 +38,19 @@ jobs:
# Cancel current runs if they're still running
# (saves processing on fast pushes)
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1
with:
access_token: ${{ github.token }}
# Allow opt-out for some users
- name: Should I Stay Or Should I Go
uses: actions/github-script@v4
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: check
with:
script: |
// If you'd like not to run this code on your commits, add your github user id here:
NO_AUTOFIX_USERS = []
NO_AUTOFIX_USERS = ["copybara-service[bot]"]
const { owner, repo } = context.repo
console.log("Actor: " + context.actor);
if (NO_AUTOFIX_USERS.includes(context.actor)) {
console.log('Cancelling');
const run_id = "${{ github.run_id }}";
@ -65,7 +66,7 @@ jobs:
run: test "${{ steps.check.outputs.result }}" = "stay"
# Setup to run sanity suite
- name: Install Python Interpreter
uses: actions/setup-python@v4
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
with:
python-version: 3.8
- name: Install Python Packages
@ -74,7 +75,7 @@ jobs:
sudo apt-get update
sudo apt-get install python3-dev
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
submodules: True
- name: Get the upstream code
@ -89,7 +90,7 @@ jobs:
run: ANDROID_NDK_HOME= ${{ github.workspace }}/tools/distrib/sanitize.sh
# Report back with a PR if things are broken
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
uses: peter-evans/create-pull-request@b1ddad2c994a25fbc81a28b3ec0e368bb2021c50 # v6.0.0
with:
delete-branch: true
branch-suffix: short-commit-hash

@ -1,32 +0,0 @@
name: PR Title Check & Tag
on:
pull_request_target:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read # to determine modified files (actions/labeler)
jobs:
triage:
permissions:
contents: read # to determine modified files (actions/labeler)
pull-requests: write # to add labels to PRs (actions/labeler)
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v3
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: ""
title-check:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: thehanimo/pr-title-checker@v1.3.5
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pass_on_octokit_error: false
configuration_path: ".github/pr_title_checker_config.json"

@ -0,0 +1,19 @@
name: PR Auto Tag
on:
pull_request_target:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read # to determine modified files (actions/labeler)
jobs:
triage:
permissions:
contents: read # to determine modified files (actions/labeler)
pull-requests: write # to add labels to PRs (actions/labeler)
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: false

@ -1,73 +0,0 @@
name: PSM Interop
on:
pull_request:
push:
branches:
- master
permissions:
contents: read
jobs:
unittest:
# By default, only version is printed out in parens, e.g. "unittest (3.10)"
# This changes it to "unittest (python3.10)"
name: "unittest (python${{ matrix.python_version }})"
runs-on: ubuntu-latest
strategy:
matrix:
python_version: ["3.9", "3.10", "3.11"]
fail-fast: false
permissions:
pull-requests: read # Used by paths-filter to read the diff.
defaults:
run:
working-directory: 'tools/run_tests/xds_k8s_test_driver'
steps:
- uses: actions/checkout@v3
# To add this job to required GitHub checks, it's not enough to use
# the on.pull_request.paths filter. For required checks, the job needs to
# return the success status, and not be skipped.
# Using paths-filter action, we skip the setup/test steps when psm interop
# files are unchanged, and the job returns success.
- uses: dorny/paths-filter@v2
id: paths_filter
with:
filters: |
psm_interop_src:
- 'tools/run_tests/xds_k8s_test_driver/**'
- 'src/proto/grpc/testing/empty.proto'
- 'src/proto/grpc/testing/messages.proto'
- 'src/proto/grpc/testing/test.proto'
- uses: actions/setup-python@v4
if: ${{ steps.paths_filter.outputs.psm_interop_src == 'true' }}
with:
python-version: "${{ matrix.python_version }}"
cache: 'pip'
cache-dependency-path: 'tools/run_tests/xds_k8s_test_driver/requirements.lock'
- name: "Install requirements"
if: ${{ steps.paths_filter.outputs.psm_interop_src == 'true' }}
run: |
pip list
pip install --upgrade pip setuptools
pip list
pip install -r requirements.lock
pip list
- name: "Generate protos"
if: ${{ steps.paths_filter.outputs.psm_interop_src == 'true' }}
run: >
python -m grpc_tools.protoc --proto_path=../../../
--python_out=. --grpc_python_out=.
src/proto/grpc/testing/empty.proto
src/proto/grpc/testing/messages.proto
src/proto/grpc/testing/test.proto
- name: "Run unit tests"
if: ${{ steps.paths_filter.outputs.psm_interop_src == 'true' }}
run: python -m tests.unit

5
.gitignore vendored

@ -17,7 +17,7 @@ cython_debug/
dist/
htmlcov/
py3*/
python_build/
pyb/
python_pylint_venv/
src/python/grpcio_*/=*
src/python/grpcio_*/build/
@ -181,3 +181,6 @@ iwyu_build/
# fuzzer logs
fuzz-*.log
# bazel module files (MODULE.bazel will need to be removed here)
MODULE.bazel
MODULE.bazel.lock

3
.gitmodules vendored

@ -47,6 +47,3 @@
# generated file that makes Git consider the submodule dirty. This
# state can be ignored for day-to-day development on gRPC.
ignore = dirty
[submodule "third_party/upb"]
path = third_party/upb
url = https://github.com/protocolbuffers/upb.git

881
BUILD

File diff suppressed because it is too large Load Diff

@ -112,6 +112,9 @@ $ bazel build :all
$ bazel test --config=dbg //test/...
```
NOTE: If you're using Bazel 7 or newer and working with gRPC, you'll need to turn off bzlmod.
This is because gRPC isn't fully compatible with bzlmod yet. To do this, add --enable_bzlmod=false to your Bazel commands.
NOTE: If you are a gRPC maintainer and you have access to our test cluster, you should use our [gRPC's Remote Execution environment](tools/remote_build/README.md)
to get significant improvement to the build and test speed (and a bunch of other very useful features).

9979
CMakeLists.txt generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,137 @@
# Contributing to gRPC: A Step-By-Step Guide
Note: This document is not meant for Google employees.
## Prerequisites
To contribute to the gRPC codebase, you need the following:
1. An
[active GitHub account](https://docs.github.com/en/get-started/quickstart/creating-an-account-on-github)
1. [An understanding of Git and GitHub](https://docs.github.com/en/get-started/using-git/about-git)
1. [Knowledge of how to fork a repository, clone a repository, merge, rebase,
resolve, push, pull, fetch
etc.](https://docs.github.com/en/get-started/using-git/about-git)
1. [git installed and working on your machine](https://github.com/git-guides/install-git)
1. Knowledge of the language being used, which can be C++, Python, Ruby,
Objective-C, PHP, or C#.
## Steps to Contribute gRPC C++ Code
The GitHub repository for the C-based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
is at https://github.com/grpc/grpc.
### Fork and Clone the Repository
If you want to contribute to the gRPC code base, you need to make a fork of the
repository.
1. Create your
[own fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)
from https://github.com/grpc/grpc.
![Screenshot of creating fork using a non-google account.](doc/images/img/grpc-create-fork.png)
1. [Clone your fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#cloning-your-forked-repository)
on your local machine.
### Prepare and Push Your Commit
1. In your cloned repository, create a new branch from `master`.
1. Then prepare a commit for the files that you want to contribute.
1. Commit to this branch.
1. Push the commit to your fork on GitHub.
Take care that your commits are aligned with these
[guidelines](https://github.com/grpc/grpc/blob/master/CONTRIBUTING.md#guidelines-for-pull-requests).
### Prepare a Pull Request
After pushing your commit, visit https://github.com/grpc/grpc . If the
forking, branch creation, commit and push have been successful, you will see
the following message:
![Screenshot of Github UI to help to create a pull request.](doc/images/img/grpc-compare-and-pull-request.png)
Take care to allow edits by maintainers. If there is a specific issue
with your pull request, the maintainer can help if needed. This access to help will reduce
the turnaround time for your submission.
![Screenshot of Github UI to help to create a Pull Request.](doc/images/img/grpc-pull-request-details.png)
Create a pull request.
### Pull Request Status - Safe Review
Once the pull request is ready, you must wait for a reviewer to be
assigned to your pull request.
If you see *Not Covered* in the EasyCLA screen, as shown in the following image,
click on the mentioned link to start the authorization process.
![Screenshot of waiting for safe review](doc/images/img/grpc-tests.png)
You will see a series of screens:
1. Select *Authorize LF-Engineering:
![Screenshot of EasyCLA Step 1](doc/images/img/grpc-easycla-authorize.png)
1. Select your contributor type:
![Screenshot of EasyCLA Step 2](doc/images/img/grpc-contributor-type.png)
1. Select *SIGN CLA*:
![Screenshot of EasyCLA Step 3](doc/images/img/grpc-sign-cla.png)
Some time after you've digitally signed the document, the EasyCLA will appear as
*Covered*.
![Screenshot of EasyCLA Step 5](doc/images/img/grpc-easycla-covered.png)
After a few hours, you will notice a new "assignee" assigned to the pull request.
![Screenshot after an assignee is added](doc/images/img/grpc-assignee.png)
After a reviewer is assigned to you, they will help with the next
steps, which are as follows:
1. You complete the code review and address the comments.
1. Your reviewer may add a few labels as needed.
### Pull Request Status - Green
Once you have approval from the reviewer, check if the tests are running. After
the tests are complete, look at the status of all the tests. If
everything is green, everything is good. But usually some failures exist. If
there are failures, select each failure. The selection will take you to a page
that has error details. Try to fix the issue.
### Pull Request Approval
For pull requests that are non-trivial, there is a thorough code review process.
You can read more about the process and requirements
[here](https://github.com/grpc/grpc/blob/master/CONTRIBUTING.md#guidelines-for-pull-requests).
After you fix the code review, you will finally get an approval. After getting
approval, you can submit the pull request.
![Pull request approved and labelled](doc/images/img/grpc-review-complete.png)
### Submission
You **cannot** do submission or merge of a pull request through Github.
![Pull request approved and labelled](doc/images/img/grpc-wait-for-merge.png)
After you have approval from a reviewer, a Google employee will trigger
the submission process. When the submission happens:
1. A commit with your changes, along with a few additional formatting changes, will
be committed to the `grpc/master` branch.
![Copybara commit](doc/images/img/grpc-copybara-commit.png)
1. The pull request you originally created will be closed.
![Pull request closed by copybara](doc/images/img/grpc-pr-closed-by-copybara.png)

@ -8,6 +8,7 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB
for general contribution guidelines.
## Maintainers (in alphabetical order)
<!-- go/keep-sorted start case=no -->
- [a11r](https://github.com/a11r), Google LLC
- [apolcyn](https://github.com/apolcyn), Google LLC
- [arjunroy](https://github.com/arjunroy), Google LLC
@ -21,6 +22,7 @@ for general contribution guidelines.
- [guantaol](https://github.com/guantaol), Google LLC
- [hcaseyal](https://github.com/hcaseyal), Google LLC
- [jtattermusch](https://github.com/jtattermusch), Google LLC
- [kevinnilson](https://github.com/kevinnilson), Google LLC
- [LittleCVR](https://github.com/littlecvr), Google LLC
- [markdroth](https://github.com/markdroth), Google LLC
- [matthewstevenson88](https://github.com/matthewstevenson88), Google LLC
@ -33,13 +35,16 @@ for general contribution guidelines.
- [soheilhy](https://github.com/soheilhy), Google LLC
- [stanley-cheung](https://github.com/stanley-cheung), Google LLC
- [thisisnotapril](https://github.com/thisisnotapril), Google LLC
- [tjagtap](https://github.com/tjagtap), Google LLC
- [veblush](https://github.com/veblush), Google LLC
- [vishalpowar](https://github.com/vishalpowar), Google LLC
- [wenbozhu](https://github.com/wenbozhu), Google LLC
- [yashykt](https://github.com/yashykt), Google LLC
- [ZhouyihaiDing](https://github.com/ZhouyihaiDing), Google LLC
<!-- go/keep-sorted end -->
## Emeritus Maintainers (in alphabetical order)
<!-- go/keep-sorted start case=no -->
- [adelez](https://github.com/adelez), Google LLC
- [AspirinSJL](https://github.com/AspirinSJL), Google LLC
- [billfeng327](https://github.com/billfeng327), Google LLC
@ -86,3 +91,4 @@ for general contribution guidelines.
- [yihuazhang](https://github.com/yihuazhang), Google LLC
- [zpencer](https://github.com/zpencer), Google LLC
- [ZhenLian](https://github.com/ZhenLian), Google LLC
<!-- go/keep-sorted end -->

2033
Makefile generated

File diff suppressed because it is too large Load Diff

@ -1,3 +0,0 @@
# Top level ownership
@markdroth **/OWNERS
@a11r **/OWNERS

1866
Package.swift generated

File diff suppressed because it is too large Load Diff

@ -26,20 +26,21 @@ runtime comes as a package available in a user's language package manager.
For instructions on how to use the language-specific gRPC runtime for a project,
please refer to these documents
- [C++](src/cpp): follow the instructions under the `src/cpp` directory
- [C#/.NET](https://github.com/grpc/grpc-dotnet): NuGet packages `Grpc.Net.Client`, `Grpc.AspNetCore.Server`
- [Dart](https://github.com/grpc/grpc-dart): pub package `grpc`
- [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc`
- [Java](https://github.com/grpc/grpc-java): Use JARs from Maven Central
Repository
- [Kotlin](https://github.com/grpc/grpc-kotlin): Use JARs from Maven Central
Repository
- [Node](https://github.com/grpc/grpc-node): `npm install @grpc/grpc-js`
- [Objective-C](src/objective-c): Add `gRPC-ProtoRPC` dependency to podspec
- [PHP](src/php): `pecl install grpc`
- [Python](src/python/grpcio): `pip install grpcio`
- [Ruby](src/ruby): `gem install grpc`
- [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions
- [C++](src/cpp): follow the instructions under the `src/cpp` directory
- [C#/.NET](https://github.com/grpc/grpc-dotnet): NuGet packages
`Grpc.Net.Client`, `Grpc.AspNetCore.Server`
- [Dart](https://github.com/grpc/grpc-dart): pub package `grpc`
- [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc`
- [Java](https://github.com/grpc/grpc-java): Use JARs from Maven Central
Repository
- [Kotlin](https://github.com/grpc/grpc-kotlin): Use JARs from Maven Central
Repository
- [Node](https://github.com/grpc/grpc-node): `npm install @grpc/grpc-js`
- [Objective-C](src/objective-c): Add `gRPC-ProtoRPC` dependency to podspec
- [PHP](src/php): `pecl install grpc`
- [Python](src/python/grpcio): `pip install grpcio`
- [Ruby](src/ruby): `gem install grpc`
- [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions
Per-language quickstart guides and tutorials can be found in the
[documentation section on the grpc.io website](https://grpc.io/docs/). Code
@ -66,8 +67,7 @@ gRPC.
## Performance
See the
[Performance dashboard](https://grafana-dot-grpc-testing.appspot.com/)
See the [Performance dashboard](https://grafana-dot-grpc-testing.appspot.com/)
for performance numbers of master branch daily builds.
## Concepts
@ -77,28 +77,28 @@ See [gRPC Concepts](CONCEPTS.md)
## About This Repository
This repository contains source code for gRPC libraries implemented in multiple
languages written on top of a shared C core library [src/core](src/core).
languages written on top of a shared C++ core library [src/core](src/core).
Libraries in different languages may be in various states of development. We are
seeking contributions for all of these libraries:
| Language | Source |
| ----------------------- | ---------------------------------- |
| Shared C [core library] | [src/core](src/core) |
| C++ | [src/cpp](src/cpp) |
| Ruby | [src/ruby](src/ruby) |
| Python | [src/python](src/python) |
| PHP | [src/php](src/php) |
| C# (core library based) | [src/csharp](src/csharp) |
| Objective-C | [src/objective-c](src/objective-c) |
| Language | Source repo |
| -------------------- | -------------------------------------------------- |
| Java | [grpc-java](https://github.com/grpc/grpc-java) |
| Kotlin | [grpc-kotlin](https://github.com/grpc/grpc-kotlin) |
| Go | [grpc-go](https://github.com/grpc/grpc-go) |
| NodeJS | [grpc-node](https://github.com/grpc/grpc-node) |
| WebJS | [grpc-web](https://github.com/grpc/grpc-web) |
| Dart | [grpc-dart](https://github.com/grpc/grpc-dart) |
| .NET (pure C# impl.) | [grpc-dotnet](https://github.com/grpc/grpc-dotnet) |
| Swift | [grpc-swift](https://github.com/grpc/grpc-swift) |
Language | Source
------------------------- | ----------------------------------
Shared C++ [core library] | [src/core](src/core)
C++ | [src/cpp](src/cpp)
Ruby | [src/ruby](src/ruby)
Python | [src/python](src/python)
PHP | [src/php](src/php)
C# (core library based) | [src/csharp](src/csharp)
Objective-C | [src/objective-c](src/objective-c)
Language | Source repo
-------------------- | --------------------------------------------------
Java | [grpc-java](https://github.com/grpc/grpc-java)
Kotlin | [grpc-kotlin](https://github.com/grpc/grpc-kotlin)
Go | [grpc-go](https://github.com/grpc/grpc-go)
NodeJS | [grpc-node](https://github.com/grpc/grpc-node)
WebJS | [grpc-web](https://github.com/grpc/grpc-web)
Dart | [grpc-dart](https://github.com/grpc/grpc-dart)
.NET (pure C# impl.) | [grpc-dotnet](https://github.com/grpc/grpc-dotnet)
Swift | [grpc-swift](https://github.com/grpc/grpc-swift)

@ -4,6 +4,7 @@ require 'rspec/core/rake_task'
require 'rubocop/rake_task'
require 'bundler/gem_tasks'
require 'fileutils'
require 'tmpdir'
require_relative 'build_config.rb'
@ -31,7 +32,6 @@ Rake::ExtensionTask.new('grpc_c', spec) do |ext|
'x86-mingw32', 'x64-mingw32', 'x64-mingw-ucrt',
'x86_64-linux', 'x86-linux', 'aarch64-linux',
'x86_64-darwin', 'arm64-darwin',
'universal-darwin'
]
ext.cross_compiling do |spec|
spec.files = spec.files.select {
@ -144,7 +144,7 @@ task 'gem:native', [:plat] do |t, args|
verbose = ENV['V'] || '0'
grpc_config = ENV['GRPC_CONFIG'] || 'opt'
ruby_cc_versions = ['3.2.0', '3.1.0', '3.0.0', '2.7.0'].join(':')
ruby_cc_versions = ['3.3.0', '3.2.0', '3.1.0', '3.0.0', '2.7.0'].join(':')
selected_plat = "#{args[:plat]}"
# use env variable to set artifact build paralellism
@ -201,12 +201,25 @@ task 'gem:native', [:plat] do |t, args|
File.truncate('grpc_c.64-msvcrt.ruby', 0)
File.truncate('grpc_c.64-ucrt.ruby', 0)
`mkdir -p src/ruby/nativedebug/symbols`
# TODO(apolcyn): make debug symbols work on apple platforms.
# Currently we hit "objcopy: grpc_c.bundle: file format not recognized"
# TODO(apolcyn): make debug symbols work on aarch64 linux.
# Currently we hit "objcopy: Unable to recognise the format of the input file `grpc_c.so'"
unix_platforms_without_debug_symbols = ['x86_64-darwin', 'arm64-darwin', 'aarch64-linux']
unix_platforms.each do |plat|
if unix_platforms_without_debug_symbols.include?(plat)
debug_symbols_dir = ''
else
debug_symbols_dir = File.join(Dir.pwd, 'src/ruby/nativedebug/symbols')
end
run_rake_compiler(plat, <<~EOT)
#{prepare_ccache_cmd} && \
gem update --system --no-document && \
bundle && \
bundle exec rake clean && \
export GRPC_RUBY_DEBUG_SYMBOLS_OUTPUT_DIR=#{debug_symbols_dir} && \
bundle exec rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
RUBY_CC_VERSION=#{ruby_cc_versions} \
V=#{verbose} \
@ -214,6 +227,13 @@ task 'gem:native', [:plat] do |t, args|
GRPC_RUBY_BUILD_PROCS=#{nproc_override}
EOT
end
# Generate debug symbol packages to complement the native libraries we just built
unix_platforms.each do |plat|
unless unix_platforms_without_debug_symbols.include?(plat)
`bash src/ruby/nativedebug/build_package.sh #{plat}`
`cp src/ruby/nativedebug/pkg/*.gem pkg/`
end
end
end
# Define dependencies between the suites.

@ -48,7 +48,7 @@ android_workspace()
# be invoked by binder transport implementation through JNI.
local_repository(
name = "binder_transport_android_helper",
path = "./src/core/ext/transport/binder/java",
path = "src/core/ext/transport/binder/java",
)
# Prevents bazel's '...' expansion from including the following folder.
@ -59,27 +59,31 @@ local_repository(
path = "third_party/utf8_range",
)
load("@io_bazel_rules_python//python:pip.bzl", "pip_install")
load("@rules_python//python:pip.bzl", "pip_parse")
pip_install(
pip_parse(
name = "grpc_python_dependencies",
requirements = "@com_github_grpc_grpc//:requirements.bazel.txt",
requirements_lock = "@com_github_grpc_grpc//:requirements.bazel.txt",
)
load("@upb//bazel:system_python.bzl", "system_python")
load("@grpc_python_dependencies//:requirements.bzl", "install_deps")
install_deps()
load("@com_google_protobuf//bazel:system_python.bzl", "system_python")
system_python(
name = "system_python",
minimum_python_version = "3.7",
)
load("@system_python//:pip.bzl", "pip_parse")
load("@system_python//:pip.bzl", system_pip_parse = "pip_parse")
pip_parse(
system_pip_parse(
name = "pip_deps",
requirements = "@upb//python:requirements.txt",
requirements = "@com_google_protobuf//python:requirements.txt",
requirements_overrides = {
"3.11": "@upb//python:requirements_311.txt",
"3.11": "@com_google_protobuf//python:requirements_311.txt",
},
)
@ -89,6 +93,13 @@ http_archive(
url = "https://github.com/bazelbuild/rules_swift/releases/download/1.7.1/rules_swift.1.7.1.tar.gz",
)
load(
"@build_bazel_apple_support//lib:repositories.bzl",
"apple_support_dependencies",
)
apple_support_dependencies()
load(
"@build_bazel_rules_swift//swift:repositories.bzl",
"swift_rules_dependencies",

@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/_metadata.py.template`!!!
__version__ = """1.59.0.dev0"""
__version__ = """1.63.0.dev0"""

@ -1,5 +0,0 @@
set noparent
@jtattermusch
@veblush
@gnossen

148
bazel/experiments.bzl generated

@ -16,60 +16,106 @@
"""Dictionary of tags to experiments so we know when to test different experiments."""
EXPERIMENT_ENABLES = {
"absl_base64": "absl_base64",
"call_status_override_on_cancellation": "call_status_override_on_cancellation",
"call_v3": "call_v3",
"canary_client_privacy": "canary_client_privacy",
"client_idleness": "client_idleness",
"client_privacy": "client_privacy",
"event_engine_client": "event_engine_client",
"event_engine_dns": "event_engine_dns",
"event_engine_listener": "event_engine_listener",
"free_large_allocator": "free_large_allocator",
"http2_stats_fix": "http2_stats_fix",
"keepalive_fix": "keepalive_fix",
"keepalive_server_fix": "keepalive_server_fix",
"monitoring_experiment": "monitoring_experiment",
"multiping": "multiping",
"peer_state_based_framing": "peer_state_based_framing",
"pending_queue_cap": "pending_queue_cap",
"pick_first_happy_eyeballs": "pick_first_happy_eyeballs",
"promise_based_client_call": "event_engine_client,event_engine_listener,promise_based_client_call",
"promise_based_server_call": "promise_based_server_call",
"chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call,promise_based_server_call",
"registered_method_lookup_in_transport": "registered_method_lookup_in_transport",
"promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport,promise_based_server_call,registered_method_lookup_in_transport",
"round_robin_delegate_to_pick_first": "round_robin_delegate_to_pick_first",
"rstpit": "rstpit",
"schedule_cancellation_over_write": "schedule_cancellation_over_write",
"server_privacy": "server_privacy",
"tcp_frame_size_tuning": "tcp_frame_size_tuning",
"tcp_rcv_lowat": "tcp_rcv_lowat",
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"v3_backend_metric_filter": "v3_backend_metric_filter",
"v3_channel_idle_filters": "v3_channel_idle_filters",
"v3_compression_filter": "v3_compression_filter",
"v3_server_auth_filter": "v3_server_auth_filter",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
"work_serializer_dispatch": "event_engine_client,work_serializer_dispatch",
"wrr_delegate_to_pick_first": "wrr_delegate_to_pick_first",
}
EXPERIMENT_POLLERS = [
"event_engine_client",
"event_engine_dns",
"event_engine_listener",
]
EXPERIMENTS = {
"windows": {
"dbg": {
},
"off": {
"compression_test": [
"v3_compression_filter",
],
"core_end2end_test": [
"event_engine_listener",
"promise_based_server_call",
"work_serializer_dispatch",
],
"cpp_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
"endpoint_test": [
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"event_engine_listener_test": [
"event_engine_listener",
],
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"lb_unit_test": [
"work_serializer_dispatch",
],
"logging_test": [
"promise_based_server_call",
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
},
"on": {
"core_end2end_test": [
"work_stealing",
"event_engine_listener",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
"flow_control_test": [
"lazier_stream_updates",
"credential_token_tests": [
"absl_base64",
],
"event_engine_listener_test": [
"event_engine_listener",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
@ -77,6 +123,7 @@ EXPERIMENTS = {
"registered_method_lookup_in_transport",
],
"xds_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
@ -86,55 +133,48 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"compression_test": [
"v3_compression_filter",
],
"core_end2end_test": [
"event_engine_listener",
"promise_based_server_call",
"work_serializer_dispatch",
],
"cpp_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
"endpoint_test": [
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"event_engine_listener_test": [
"event_engine_listener",
],
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"lb_unit_test": [
"work_serializer_dispatch",
],
"logging_test": [
"promise_based_server_call",
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
},
"on": {
"core_end2end_test": [
"work_stealing",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
"flow_control_test": [
"lazier_stream_updates",
"credential_token_tests": [
"absl_base64",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
@ -142,6 +182,7 @@ EXPERIMENTS = {
"registered_method_lookup_in_transport",
],
"xds_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
@ -151,18 +192,17 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"cancel_ares_query_test": [
"event_engine_dns",
"compression_test": [
"v3_compression_filter",
],
"core_end2end_test": [
"chaotic_good",
"event_engine_client",
"event_engine_listener",
"promise_based_client_call",
"promise_based_server_call",
"work_serializer_dispatch",
],
"cpp_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
"endpoint_test": [
"tcp_frame_size_tuning",
@ -171,53 +211,65 @@ EXPERIMENTS = {
"event_engine_client_test": [
"event_engine_client",
],
"event_engine_listener_test": [
"event_engine_listener",
],
"flow_control_test": [
"multiping",
"peer_state_based_framing",
"rstpit",
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"lb_unit_test": [
"work_serializer_dispatch",
"lame_client_test": [
"promise_based_client_call",
],
"logging_test": [
"promise_based_server_call",
],
"resolver_component_tests_runner_invoker": [
"event_engine_dns",
],
"resource_quota_test": [
"free_large_allocator",
"memory_pressure_controller",
"unconstrained_max_quota_buffer_size",
],
"xds_end2end_test": [
"promise_based_server_call",
"work_serializer_dispatch",
],
},
"on": {
"cancel_ares_query_test": [
"event_engine_dns",
],
"core_end2end_test": [
"work_stealing",
"event_engine_listener",
"work_serializer_dispatch",
],
"cpp_end2end_test": [
"work_serializer_dispatch",
],
"cpp_lb_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"wrr_delegate_to_pick_first",
],
"flow_control_test": [
"lazier_stream_updates",
"credential_token_tests": [
"absl_base64",
],
"event_engine_listener_test": [
"event_engine_listener",
],
"lb_unit_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"work_serializer_dispatch",
"wrr_delegate_to_pick_first",
],
"resolver_component_tests_runner_invoker": [
"event_engine_dns",
],
"surface_registered_method_lookup": [
"registered_method_lookup_in_transport",
],
"xds_end2end_test": [
"pick_first_happy_eyeballs",
"round_robin_delegate_to_pick_first",
"work_serializer_dispatch",
"wrr_delegate_to_pick_first",
],
},

@ -175,7 +175,7 @@ _generate_cc = rule(
"plugin": attr.label(
executable = True,
providers = ["files_to_run"],
cfg = "host",
cfg = "exec",
),
"flags": attr.string_list(
mandatory = False,
@ -189,7 +189,7 @@ _generate_cc = rule(
"_protoc": attr.label(
default = Label("//external:protocol_compiler"),
executable = True,
cfg = "host",
cfg = "exec",
),
},
# We generate .h files, so we need to output to genfiles.

@ -166,7 +166,7 @@ generate_objc = rule(
default = "@com_github_grpc_grpc//src/compiler:grpc_objective_c_plugin",
executable = True,
providers = ["files_to_run"],
cfg = "host",
cfg = "exec",
),
"srcs": attr.string_list(
mandatory = False,
@ -182,7 +182,7 @@ generate_objc = rule(
"_protoc": attr.label(
default = Label("//external:protocol_compiler"),
executable = True,
cfg = "host",
cfg = "exec",
),
},
output_to_genfiles = True,

@ -15,7 +15,7 @@
licenses(["notice"])
package(
default_visibility = ["//visibility:public"]
default_visibility = ["//visibility:public"],
)
# This is needed for the dependency on google_cloud_cpp to work.

@ -29,11 +29,11 @@ Contains macros used throughout the repo.
load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
load("//bazel:copts.bzl", "GRPC_DEFAULT_COPTS")
load("//bazel:experiments.bzl", "EXPERIMENTS")
load("//bazel:test_experiments.bzl", "TEST_EXPERIMENTS")
load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library", "upb_proto_reflection_library")
load("//bazel:experiments.bzl", "EXPERIMENTS", "EXPERIMENT_ENABLES", "EXPERIMENT_POLLERS")
load("//bazel:test_experiments.bzl", "TEST_EXPERIMENTS", "TEST_EXPERIMENT_ENABLES", "TEST_EXPERIMENT_POLLERS")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
load("@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl", "ios_test_runner")
load("@com_google_protobuf//bazel:upb_proto_library.bzl", "upb_proto_library", "upb_proto_reflection_library")
# The set of pollers to test against if a test exercises polling
POLLERS = ["epoll1", "poll"]
@ -95,6 +95,7 @@ def _update_visibility(visibility):
"alt_grpc++_base_unsecure_legacy": PRIVATE,
"alts_frame_protector": PRIVATE,
"channelz": PRIVATE,
"chaotic_good": PRIVATE,
"client_channel": PRIVATE,
"cli": PRIVATE,
"debug_location": PRIVATE,
@ -108,18 +109,20 @@ def _update_visibility(visibility):
"grpc++_test": PRIVATE,
"http": PRIVATE,
"httpcli": PRIVATE,
"iomgr_timer": PRIVATE,
"iomgr_internal_errqueue": PRIVATE,
"iomgr_buffer_list": PRIVATE,
"json_reader_legacy": PRIVATE,
"public": PUBLIC,
"ref_counted_ptr": PRIVATE,
"tcp_tracer": PRIVATE,
"trace": PRIVATE,
"tsi_interface": PRIVATE,
"tsi": PRIVATE,
"xds": PRIVATE,
"xds_client_core": PRIVATE,
"grpc_python_observability": PRIVATE,
"event_engine_base_hdrs": PRIVATE,
"useful": PRIVATE,
}
final_visibility = []
for rule in visibility:
@ -203,8 +206,8 @@ def grpc_cc_library(
includes = [
"api/include",
"include",
"src/core/ext/upb-generated", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upbdefs-generated", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upb-gen", # Once upb code-gen issue is resolved, remove this.
"src/core/ext/upbdefs-gen", # Once upb code-gen issue is resolved, remove this.
],
alwayslink = alwayslink,
data = data,
@ -277,8 +280,10 @@ def ios_cc_test(
deps = ios_test_deps,
)
def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, uses_event_engine, flaky):
"""Common logic used to parameterize tests for every poller and EventEngine and experiment.
def expand_poller_config(name, srcs, deps, tags, args, exclude_pollers, uses_polling, uses_event_engine, flaky):
"""Common logic used to parameterize tests for every poller and EventEngine.
Used by expand_tests (repeatedly) to form base lists of pollers for each experiment.
Args:
name: base name of the test
@ -295,8 +300,12 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
Returns:
A list of dictionaries containing modified values of name, srcs, deps, tags, and args.
"""
poller_config = []
# See work_stealing_thread_pool.cc for details.
default_env = {"GRPC_THREAD_POOL_VERBOSE_FAILURES": "true"}
if not uses_polling:
tags = tags + ["no_uses_polling"]
@ -307,7 +316,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
"tags": tags,
"args": args,
"flaky": flaky,
"env": {},
"env": default_env,
})
else:
# On linux we run the same test with the default EventEngine, once for each
@ -327,7 +336,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
"args": args,
"env": {
"GRPC_POLL_STRATEGY": poller,
},
} | default_env,
"flaky": flaky,
})
@ -344,7 +353,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
"deps": deps,
"tags": tags + ["no_linux"],
"args": args,
"env": {},
"env": default_env,
"flaky": flaky,
})
else:
@ -364,10 +373,31 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
"deps": deps,
"tags": test_tags,
"args": test_args,
"env": {},
"env": default_env,
"flaky": flaky,
})
return poller_config
def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, uses_event_engine, flaky):
"""Common logic used to parameterize tests for every poller and EventEngine and experiment.
Args:
name: base name of the test
srcs: source files
deps: base deps
tags: base tags
args: base args
flaky: base flaky
exclude_pollers: list of poller names to exclude for this set of tests.
uses_polling: set to False if the test is not sensitive to polling methodology.
uses_event_engine: set to False if the test is not sensitive to
EventEngine implementation differences
Returns:
A list of dictionaries containing modified values of name, srcs, deps, tags, and args.
"""
experiments = {}
# buildifier: disable=uninitialized
@ -416,19 +446,35 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
tags.append("no_test_ios")
return tags
experiment_config = list(poller_config)
base_params = {
"name": name,
"srcs": srcs,
"deps": deps,
"tags": tags,
"args": args,
"exclude_pollers": exclude_pollers,
"uses_polling": uses_polling,
"uses_event_engine": uses_event_engine,
"flaky": flaky,
}
experiment_config = expand_poller_config(**base_params)
experiment_enables = {k: v for k, v in EXPERIMENT_ENABLES.items() + TEST_EXPERIMENT_ENABLES.items()}
experiment_pollers = EXPERIMENT_POLLERS + TEST_EXPERIMENT_POLLERS
for mode, config in mode_config.items():
enabled_tags, disabled_tags = config
if enabled_tags != None:
for experiment in experiments[mode].keys():
for config in poller_config:
experiment_params = dict(base_params)
experiment_params["uses_polling"] = uses_polling and (experiment in experiment_pollers)
for config in expand_poller_config(**experiment_params):
config = dict(config)
config["name"] = config["name"] + "@experiment=" + experiment
env = dict(config["env"])
env["GRPC_EXPERIMENTS"] = experiment
env["GRPC_EXPERIMENTS"] = experiment_enables[experiment]
env["GRPC_CI_EXPERIMENTS"] = "1"
config["env"] = env
tags = config["tags"]
tags = config["tags"] + ["experiment_variation"]
for tag in must_have_tags + enabled_tags:
if tag not in tags:
tags = tags + [tag]
@ -437,14 +483,16 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, us
experiment_config.append(config)
if disabled_tags != None:
for experiment in experiments[mode].keys():
for config in poller_config:
experiment_params = dict(base_params)
experiment_params["uses_polling"] = uses_polling and (experiment in experiment_pollers)
for config in expand_poller_config(**experiment_params):
config = dict(config)
config["name"] = config["name"] + "@experiment=no_" + experiment
env = dict(config["env"])
env["GRPC_EXPERIMENTS"] = "-" + experiment
env["GRPC_CI_EXPERIMENTS"] = "1"
config["env"] = env
tags = config["tags"]
tags = config["tags"] + ["experiment_variation"]
for tag in must_have_tags + disabled_tags:
if tag not in tags:
tags = tags + [tag]

@ -21,43 +21,53 @@ def grpc_deps():
"""Loads dependencies need to compile and test the grpc library."""
native.bind(
name = "upb_lib",
actual = "@upb//:upb",
name = "upb_amalgamation_lib",
actual = "@com_google_protobuf//upb:amalgamation",
)
native.bind(
name = "upb_collections_lib",
actual = "@upb//:collections",
name = "upb_base_lib",
actual = "@com_google_protobuf//upb/base",
)
native.bind(
name = "upb_message_lib",
actual = "@com_google_protobuf//upb:message",
)
native.bind(
name = "upb_mem_lib",
actual = "@com_google_protobuf//upb/mem",
)
native.bind(
name = "upb_reflection",
actual = "@upb//:reflection",
actual = "@com_google_protobuf//upb:reflection",
)
native.bind(
name = "upb_lib_descriptor",
actual = "@upb//:descriptor_upb_proto",
actual = "@com_google_protobuf//upb:descriptor_upb_proto",
)
native.bind(
name = "upb_lib_descriptor_reflection",
actual = "@upb//:descriptor_upb_proto_reflection",
actual = "@com_google_protobuf//upb:descriptor_upb_proto_reflection",
)
native.bind(
name = "upb_textformat_lib",
actual = "@upb//:textformat",
actual = "@com_google_protobuf//upb/text",
)
native.bind(
name = "upb_json_lib",
actual = "@upb//:json",
actual = "@com_google_protobuf//upb/json",
)
native.bind(
name = "upb_generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
actual = "@upb//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
actual = "@com_google_protobuf//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
)
native.bind(
@ -215,16 +225,26 @@ def grpc_deps():
actual = "@com_google_googleapis//google/logging/v2:logging_cc_proto",
)
if "platforms" not in native.existing_rules():
http_archive(
name = "platforms",
sha256 = "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz",
"https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz",
],
)
if "boringssl" not in native.existing_rules():
http_archive(
name = "boringssl",
# Use github mirror instead of https://boringssl.googlesource.com/boringssl
# to obtain a boringssl archive with consistent sha256
sha256 = "b21994a857a7aa6d5256ffe355c735ad4c286de44c6c81dfc04edc41a8feaeef",
strip_prefix = "boringssl-2ff4b968a7e0cfee66d9f151cb95635b43dc1d5b",
sha256 = "057f662b0e85931a84945b2e89ba201fd44b0583da827c948fe443593690fb83",
strip_prefix = "boringssl-ae72a4514c7afd150596b0a80947f3ca9b8363b5",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/boringssl/archive/2ff4b968a7e0cfee66d9f151cb95635b43dc1d5b.tar.gz",
"https://github.com/google/boringssl/archive/2ff4b968a7e0cfee66d9f151cb95635b43dc1d5b.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/boringssl/archive/ae72a4514c7afd150596b0a80947f3ca9b8363b5.tar.gz",
"https://github.com/google/boringssl/archive/ae72a4514c7afd150596b0a80947f3ca9b8363b5.tar.gz",
],
)
@ -232,23 +252,23 @@ def grpc_deps():
http_archive(
name = "zlib",
build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD",
sha256 = "90f43a9c998740e8a0db24b0af0147033db2aaaa99423129abbd76640757cac9",
strip_prefix = "zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc",
sha256 = "18337cdb32562003c39d9f7322b9a166ad4abfb2b909566428e11f96d2385586",
strip_prefix = "zlib-09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/madler/zlib/archive/04f42ceca40f73e2978b50e93806c2a18c1281fc.tar.gz",
"https://github.com/madler/zlib/archive/04f42ceca40f73e2978b50e93806c2a18c1281fc.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/madler/zlib/archive/09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851.tar.gz",
"https://github.com/madler/zlib/archive/09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851.tar.gz",
],
)
if "com_google_protobuf" not in native.existing_rules():
http_archive(
name = "com_google_protobuf",
sha256 = "660ce016f987550bc1ccec4a6ee4199afb871799b696227098e3641476a7d566",
strip_prefix = "protobuf-b2b7a51158418f41cff0520894836c15b1738721",
sha256 = "70f480fe9cb0c6829dbf6be3c388103313aacb65de667b86d981bbc9eaedb905",
strip_prefix = "protobuf-7f94235e552599141950d7a4a3eaf93bc87d1b22",
urls = [
# https://github.com/protocolbuffers/protobuf/commits/v24.3
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz",
# https://github.com/protocolbuffers/protobuf/commits/v25.0
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/7f94235e552599141950d7a4a3eaf93bc87d1b22.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/7f94235e552599141950d7a4a3eaf93bc87d1b22.tar.gz",
],
patches = [
"@com_github_grpc_grpc//third_party:protobuf.patch",
@ -259,11 +279,11 @@ def grpc_deps():
if "com_google_googletest" not in native.existing_rules():
http_archive(
name = "com_google_googletest",
sha256 = "c8de6c60e12ad014a28225c5247ee735861d85cf906df617f6a29954ca05f547",
strip_prefix = "googletest-0e402173c97aea7a00749e825b194bfede4f2e45",
sha256 = "31bf78bd91b96dd5e24fab3bb1d7f3f7453ccbaceec9afb86d6e4816a15ab109",
strip_prefix = "googletest-2dd1c131950043a8ad5ab0d2dda0e0970596586a",
urls = [
# 2022-02-09
"https://github.com/google/googletest/archive/0e402173c97aea7a00749e825b194bfede4f2e45.tar.gz",
# 2023-10-09
"https://github.com/google/googletest/archive/2dd1c131950043a8ad5ab0d2dda0e0970596586a.tar.gz",
],
)
@ -283,22 +303,22 @@ def grpc_deps():
if "rules_cc" not in native.existing_rules():
http_archive(
name = "rules_cc",
sha256 = "3d9e271e2876ba42e114c9b9bc51454e379cbf0ec9ef9d40e2ae4cec61a31b40",
strip_prefix = "rules_cc-0.0.6",
sha256 = "2037875b9a4456dce4a79d112a8ae885bbc4aad968e6587dca6e64f3a0900cdf",
strip_prefix = "rules_cc-0.0.9",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/rules_cc/releases/download/0.0.6/rules_cc-0.0.6.tar.gz",
"https://github.com/bazelbuild/rules_cc/releases/download/0.0.6/rules_cc-0.0.6.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz",
"https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz",
],
)
if "com_github_google_benchmark" not in native.existing_rules():
http_archive(
name = "com_github_google_benchmark",
sha256 = "4e47ca279d5ae967c506c136bd8afb42eedcaf010aebb48a0e87790cae4b488a",
strip_prefix = "benchmark-015d1a091af6937488242b70121858bce8fd40e9",
sha256 = "8e7b955f04bc6984e4f14074d0d191474f76a6c8e849e04a9dced49bc975f2d4",
strip_prefix = "benchmark-344117638c8ff7e239044fd0fa7085839fc03021",
urls = [
# v1.8.2
"https://github.com/google/benchmark/archive/015d1a091af6937488242b70121858bce8fd40e9.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/benchmark/archive/344117638c8ff7e239044fd0fa7085839fc03021.tar.gz",
"https://github.com/google/benchmark/archive/344117638c8ff7e239044fd0fa7085839fc03021.tar.gz",
],
)
@ -328,11 +348,11 @@ def grpc_deps():
if "com_google_absl" not in native.existing_rules():
http_archive(
name = "com_google_absl",
sha256 = "59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5",
strip_prefix = "abseil-cpp-20230802.0",
sha256 = "338420448b140f0dfd1a1ea3c3ce71b3bc172071f24f4d9a57d59b45037da440",
strip_prefix = "abseil-cpp-20240116.0",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/abseil/abseil-cpp/archive/20230802.0.tar.gz",
"https://github.com/abseil/abseil-cpp/archive/20230802.0.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz",
"https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz",
],
)
@ -380,26 +400,14 @@ def grpc_deps():
],
)
if "upb" not in native.existing_rules():
http_archive(
name = "upb",
sha256 = "5147e0ab6a28421d1e49004f4a205d84f06b924585e15eaa884cfe13289165b7",
strip_prefix = "upb-42cd08932e364a4cde35033b73f15c30250d7c2e",
urls = [
# https://github.com/protocolbuffers/upb/commits/24.x
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz",
"https://github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz",
],
)
if "envoy_api" not in native.existing_rules():
http_archive(
name = "envoy_api",
sha256 = "6fd3496c82919a433219733819a93b56699519a193126959e9c4fedc25e70663",
strip_prefix = "data-plane-api-e53e7bbd012f81965f2e79848ad9a58ceb67201f",
sha256 = "ddd3beedda1178a79e0d988f76f362002aced09749452515853f106e22bd2249",
strip_prefix = "data-plane-api-78f198cf96ecdc7120ef640406770aa01af775c4",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/envoyproxy/data-plane-api/archive/e53e7bbd012f81965f2e79848ad9a58ceb67201f.tar.gz",
"https://github.com/envoyproxy/data-plane-api/archive/e53e7bbd012f81965f2e79848ad9a58ceb67201f.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/envoyproxy/data-plane-api/archive/78f198cf96ecdc7120ef640406770aa01af775c4.tar.gz",
"https://github.com/envoyproxy/data-plane-api/archive/78f198cf96ecdc7120ef640406770aa01af775c4.tar.gz",
],
)
@ -416,20 +424,20 @@ def grpc_deps():
if "build_bazel_rules_apple" not in native.existing_rules():
http_archive(
name = "build_bazel_rules_apple",
sha256 = "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911",
sha256 = "34c41bfb59cdaea29ac2df5a2fa79e5add609c71bb303b2ebb10985f93fa20e7",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz",
"https://github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/rules_apple/releases/download/3.1.1/rules_apple.3.1.1.tar.gz",
"https://github.com/bazelbuild/rules_apple/releases/download/3.1.1/rules_apple.3.1.1.tar.gz",
],
)
if "build_bazel_apple_support" not in native.existing_rules():
http_archive(
name = "build_bazel_apple_support",
sha256 = "f4fdf5c9b42b92ea12f229b265d74bb8cedb8208ca7a445b383c9f866cf53392",
sha256 = "cf4d63f39c7ba9059f70e995bf5fe1019267d3f77379c2028561a5d7645ef67c",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/apple_support/releases/download/1.3.1/apple_support.1.3.1.tar.gz",
"https://github.com/bazelbuild/apple_support/releases/download/1.3.1/apple_support.1.3.1.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/bazelbuild/apple_support/releases/download/1.11.1/apple_support.1.11.1.tar.gz",
"https://github.com/bazelbuild/apple_support/releases/download/1.11.1/apple_support.1.11.1.tar.gz",
],
)
@ -478,14 +486,14 @@ def grpc_deps():
patch_args = ["-p1"],
)
if "com_github_cncf_udpa" not in native.existing_rules():
if "com_github_cncf_xds" not in native.existing_rules():
http_archive(
name = "com_github_cncf_udpa",
sha256 = "0d33b83f8c6368954e72e7785539f0d272a8aba2f6e2e336ed15fd1514bc9899",
strip_prefix = "xds-e9ce68804cb4e64cab5a52e3c8baf840d4ff87b7",
name = "com_github_cncf_xds",
sha256 = "dc305e20c9fa80822322271b50aa2ffa917bf4fd3973bcec52bfc28dc32c5927",
strip_prefix = "xds-3a472e524827f72d1ad621c4983dd5af54c46776",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/e9ce68804cb4e64cab5a52e3c8baf840d4ff87b7.tar.gz",
"https://github.com/cncf/xds/archive/e9ce68804cb4e64cab5a52e3c8baf840d4ff87b7.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/3a472e524827f72d1ad621c4983dd5af54c46776.tar.gz",
"https://github.com/cncf/xds/archive/3a472e524827f72d1ad621c4983dd5af54c46776.tar.gz",
],
)
@ -509,22 +517,22 @@ def grpc_deps():
if "io_opentelemetry_cpp" not in native.existing_rules():
http_archive(
name = "io_opentelemetry_cpp",
sha256 = "f30cd88bf898a5726d245eba882b8e81012021eb00df34109f4dfb203f005cea",
strip_prefix = "opentelemetry-cpp-1.11.0",
sha256 = "7735cc56507149686e6019e06f588317099d4522480be5f38a2a09ec69af1706",
strip_prefix = "opentelemetry-cpp-1.13.0",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz",
"https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.13.0.tar.gz",
"https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.13.0.tar.gz",
],
)
if "google_cloud_cpp" not in native.existing_rules():
http_archive(
name = "google_cloud_cpp",
sha256 = "371d01b03c7e2604d671b8fa1c86710abe3b524a78bc2705a6bb4de715696755",
strip_prefix = "google-cloud-cpp-2.14.0",
sha256 = "7ca7f583b60d2aa1274411fed3b9fb3887119b2e84244bb3fc69ea1db819e4e5",
strip_prefix = "google-cloud-cpp-2.16.0",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.14.0.tar.gz",
"https://github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.14.0.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.16.0.tar.gz",
"https://github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.16.0.tar.gz",
],
)
@ -610,11 +618,11 @@ def grpc_test_only_deps():
if "com_google_libprotobuf_mutator" not in native.existing_rules():
http_archive(
name = "com_google_libprotobuf_mutator",
sha256 = "11ab4c57b4051977d8fedb86dba5c9092e578bc293c47be146e0b0596b6a0bdc",
sha256 = "9c8f800aed088cdf89adc3eaaa66b56b4da7da041f26338aa71a2ab43d860d46",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/libprotobuf-mutator/archive/c390388561be36f94a559a4aed7e2fe60470f60b.tar.gz",
"https://github.com/google/libprotobuf-mutator/archive/c390388561be36f94a559a4aed7e2fe60470f60b.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/libprotobuf-mutator/archive/1f95f8083066f5b38fd2db172e7e7f9aa7c49d2d.tar.gz",
"https://github.com/google/libprotobuf-mutator/archive/1f95f8083066f5b38fd2db172e7e7f9aa7c49d2d.tar.gz",
],
strip_prefix = "libprotobuf-mutator-c390388561be36f94a559a4aed7e2fe60470f60b",
strip_prefix = "libprotobuf-mutator-1f95f8083066f5b38fd2db172e7e7f9aa7c49d2d",
build_file = "@com_github_grpc_grpc//third_party:libprotobuf_mutator.BUILD",
)

@ -22,7 +22,7 @@ load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@envoy_api//bazel:repositories.bzl", "api_dependencies")
load("@google_cloud_cpp//bazel:google_cloud_cpp_deps.bzl", "google_cloud_cpp_deps")
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
load("@rules_python//python:repositories.bzl", "py_repositories")
def grpc_extra_deps(ignore_version_differences = False):
"""Loads the extra dependencies.
@ -49,8 +49,6 @@ def grpc_extra_deps(ignore_version_differences = False):
"""
protobuf_deps()
upb_deps()
api_dependencies()
go_rules_dependencies()
@ -74,3 +72,5 @@ def grpc_extra_deps(ignore_version_differences = False):
)
google_cloud_cpp_deps()
py_repositories()

@ -19,13 +19,12 @@ load("@com_github_grpc_grpc//third_party/py:python_configure.bzl", "python_confi
# buildifier: disable=unnamed-macro
def grpc_python_deps():
"""Loads dependencies for gRPC Python."""
if "io_bazel_rules_python" not in native.existing_rules():
if "rules_python" not in native.existing_rules():
http_archive(
name = "io_bazel_rules_python",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.4.0/rules_python-0.4.0.tar.gz",
sha256 = "954aa89b491be4a083304a2cb838019c8b8c3720a7abb9c4cb81ac7a24230cea",
patches = ["@com_github_grpc_grpc//third_party:rules_python.patch"],
patch_args = ["-p1"],
name = "rules_python",
sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b",
strip_prefix = "rules_python-0.26.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz",
)
python_configure(name = "local_config_python")

@ -113,7 +113,7 @@ _gen_py_aspect = aspect(
default = Label("//external:protocol_compiler"),
providers = ["files_to_run"],
executable = True,
cfg = "host",
cfg = "exec",
),
"_protobuf_library": attr.label(
default = Label("@com_google_protobuf//:protobuf_python"),
@ -169,7 +169,7 @@ py_proto_library = rule(
default = Label("//external:protocol_compiler"),
providers = ["files_to_run"],
executable = True,
cfg = "host",
cfg = "exec",
),
"_protobuf_library": attr.label(
default = Label("@com_google_protobuf//:protobuf_python"),
@ -222,11 +222,11 @@ def _generate_pb2_grpc_src_impl(context):
py_info = _merge_pyinfos(
[
p,
context.attr._grpc_library[PyInfo],
context.attr.grpc_library[PyInfo],
] + [dep[PyInfo] for dep in context.attr.py_deps],
)
runfiles = context.runfiles(files = out_files, transitive_files = py_info.transitive_sources).merge(context.attr._grpc_library[DefaultInfo].data_runfiles)
runfiles = context.runfiles(files = out_files, transitive_files = py_info.transitive_sources).merge(context.attr.grpc_library[DefaultInfo].data_runfiles)
return [
DefaultInfo(
@ -252,16 +252,16 @@ _generate_pb2_grpc_src = rule(
"_grpc_plugin": attr.label(
executable = True,
providers = ["files_to_run"],
cfg = "host",
cfg = "exec",
default = Label("//src/compiler:grpc_python_plugin"),
),
"_protoc": attr.label(
executable = True,
providers = ["files_to_run"],
cfg = "host",
cfg = "exec",
default = Label("//external:protocol_compiler"),
),
"_grpc_library": attr.label(
"grpc_library": attr.label(
default = Label("//src/python/grpcio/grpc:grpcio"),
providers = [PyInfo],
),
@ -274,6 +274,7 @@ def py_grpc_library(
srcs,
deps,
strip_prefixes = [],
grpc_library = Label("//src/python/grpcio/grpc:grpcio"),
**kwargs):
"""Generate python code for gRPC services defined in a protobuf.
@ -287,6 +288,9 @@ def py_grpc_library(
stripped from the beginning of foo_pb2 modules imported by the
generated stubs. This is useful in combination with the `imports`
attribute of the `py_library` rule.
grpc_library: (`label`) a single `py_library` target representing the
python gRPC library target to be depended upon. This can be used to
generate code that depends on `grpcio` from the Python Package Index.
**kwargs: Additional arguments to be supplied to the invocation of
py_library.
"""
@ -301,5 +305,6 @@ def py_grpc_library(
deps = srcs,
py_deps = deps,
strip_prefixes = strip_prefixes,
grpc_library = grpc_library,
**kwargs
)

@ -1,2 +1,2 @@
6.3.2
5.4.1
6.4.0
7.0.0

@ -16,6 +16,16 @@
"""Dictionary of tags to experiments so we know when to test different experiments."""
TEST_EXPERIMENT_ENABLES = {
"test_experiment_1": "test_experiment_1",
"test_experiment_2": "test_experiment_2",
"test_experiment_3": "test_experiment_3",
"test_experiment_4": "test_experiment_4",
}
TEST_EXPERIMENT_POLLERS = [
]
TEST_EXPERIMENTS = {
"windows": {
"dbg": {

@ -57,17 +57,12 @@ function upload {
# upload "github.com/google/boringssl/archive/1c2769383f027befac5b75b6cedd25daf3bf4dcf.tar.gz"
# bazel binaries used by the tools/bazel wrapper script
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/5.4.1/bazel-5.4.1-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.3.2/bazel-6.3.2-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/7.0.0/bazel-7.0.0-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/7.0.0/bazel-7.0.0-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/7.0.0/bazel-7.0.0-windows-x86_64.exe
# Collect the github archives to mirror from grpc_deps.bzl
grep -o '"https://github.com/[^"]*"' bazel/grpc_deps.bzl | sed 's/^"https:\/\///' | sed 's/"$//' | while read -r line ; do

@ -19,8 +19,12 @@ extend-exclude = '''
| src/python/grpcio/grpc/_grpcio_metadata.py
# AUTO-GENERATED BY make_grpcio_tools.py
| tools/distrib/python/grpcio_tools/protoc_lib_deps.py
# AUTO-GENERATED BY make_grpcio_observability.py
| src/python/grpcio_observability/observability_lib_deps.py
| .*_pb2.py # autogenerated Protocol Buffer files
| .*_pb2_grpc.py # autogenerated Protocol Buffer gRPC files
# AUTO-GENERATED By tools/distrib/python/xds_protos/build.py
| tools/distrib/python/xds_protos/.*
)
'''
@ -30,7 +34,6 @@ line_length = 80
src_paths = [
"examples/python/data_transmission",
"examples/python/async_streaming",
"tools/run_tests/xds_k8s_test_driver",
"src/python/grpcio_tests",
"tools/run_tests",
]
@ -40,11 +43,12 @@ known_first_party = [
]
known_third_party = ["grpc"]
skip_glob = [
"third_party/*",
"*/third_party/*",
"*/env/*",
"*pb2*.py",
"*pb2*.pyi",
"**/site-packages/**/*",
"tools/distrib/python/xds_protos/*",
]
single_line_exclusions = ["typing"]
force_single_line = true

File diff suppressed because it is too large Load Diff

@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-35.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-39.dll'
end

@ -12,11 +12,11 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 35.0.0
core_version: 39.0.0
csharp_major_version: 2
g_stands_for: generative
protobuf_version: 3.24.3
version: 1.59.0-dev
g_stands_for: giggle
protobuf_version: 3.25.1
version: 1.63.0-dev
configs:
asan:
CC: clang
@ -149,8 +149,8 @@ defaults:
CFLAGS: -g
COREFLAGS: -fno-exceptions
CPPFLAGS: -g -Wall -Wextra -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp -Ithird_party/re2
-Ithird_party/upb -Isrc/core/ext/upb-generated -Isrc/core/ext/upbdefs-generated
-Ithird_party/utf8_range -Ithird_party/xxhash
-Ithird_party/upb -Isrc/core/ext/upb-gen -Isrc/core/ext/upbdefs-gen -Ithird_party/utf8_range
-Ithird_party/xxhash
LDFLAGS: -g
zlib:
CFLAGS: -fvisibility=hidden
@ -207,7 +207,9 @@ swift_package:
- grpc
- grpc_authorization_provider
- gpr
- upb
- upb_base_lib
- upb_mem_lib
- upb_message_lib
- upb_json_lib
- upb_textformat_lib
- utf8_range_lib

@ -1,3 +0,0 @@
set noparent
@jtattermusch
@apolcyn

@ -15,6 +15,6 @@
set(UPB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/upb)
set(_gRPC_UPB_INCLUDE_DIR "${UPB_ROOT_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/third_party/utf8_range")
set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-generated" "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upbdefs-generated")
set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-gen" "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upbdefs-gen")
set(_gRPC_UPB_LIBRARIES upb)

1131
config.m4 generated

File diff suppressed because it is too large Load Diff

1405
config.w32 generated

File diff suppressed because it is too large Load Diff

@ -75,7 +75,7 @@ Base64-encoded values.
**ASCII-Value** should not have leading or trailing whitespace. If it contains
leading or trailing whitespace, it may be stripped. The **ASCII-Value**
character range defined is more strict than HTTP. Implementations must not error
character range defined is stricter than HTTP. Implementations must not error
due to receiving an invalid **ASCII-Value** that's a valid **field-value** in
HTTP, but the precise behavior is not strictly defined: they may throw the value
away or accept the value. If accepted, care must be taken to make sure that the

@ -34,10 +34,16 @@ grpc_extra_deps()
## Supported Versions
In general, gRPC supports building with the latest patch release of the two most
recent LTS versions of Bazel. However individual releases may have a broader
gRPC supports building with the latest stable release of Bazel,
as well as the previous major version release for at least 6 months
after it transitions into maintenance mode.
This is consistent with the supported build systems of
[the Google Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
However individual releases may have a broader
compatibility range. The currently supported versions are captured by the
following list:
- [`6.3.2`](https://github.com/bazelbuild/bazel/releases/tag/6.3.2)
- [`5.4.1`](https://github.com/bazelbuild/bazel/releases/tag/5.4.1)
- [`6.4.0`](https://github.com/bazelbuild/bazel/releases/tag/6.4.0)
- [`7.0.0`](https://github.com/bazelbuild/bazel/releases/tag/7.0.0)
NOTE: gRPC doesn't support bzlmod yet.

@ -2,37 +2,44 @@
## Overview
This document describes the command line tool that comes with gRPC repository. It is desirable to have command line
tools written in other languages roughly follow the same syntax and flags.
This document describes the command line tool that comes with gRPC repository.
It is desirable to have command line tools written in other languages roughly
follow the same syntax and flags.
At this point, the tool needs to be built from source, and it should be moved out to grpc-tools repository as a stand
alone application once it is mature enough.
> [!NOTE]
> At present, the tool needs to be built from source, and it should be moved out
> to grpc-tools repository as a stand alone application once it is mature
> enough. This tool in its current state though is not up to par in its
> user-friendliness. Other tools in the ecosystem, for example,
> [grpcurl](https://github.com/fullstorydev/grpcurl) are better maintained.
## Core functionality
The command line tool can do the following things:
- Send unary rpc.
- Attach metadata and display received metadata.
- Handle common authentication to server.
- Infer request/response types from server reflection result.
- Find the request/response types from a given proto file.
- Read proto request in text form.
- Read request in wire form (for protobuf messages, this means serialized binary form).
- Display proto response in text form.
- Write response in wire form to a file.
- Send unary rpc.
- Attach metadata and display received metadata.
- Handle common authentication to server.
- Infer request/response types from server reflection result.
- Find the request/response types from a given proto file.
- Read proto request in text form.
- Read request in wire form (for protobuf messages, this means serialized
binary form).
- Display proto response in text form.
- Write response in wire form to a file.
The command line tool should support the following things:
- List server services and methods through server reflection.
- Fine-grained auth control (such as, use this oauth token to talk to the server).
- Send streaming rpc.
- List server services and methods through server reflection.
- Fine-grained auth control (such as, use this oauth token to talk to the
server).
- Send streaming rpc.
## Code location
To use the tool, you need to get the grpc repository and make sure your system
has the prerequisites for building grpc from source, given in the [installation
instructions](../BUILDING.md).
has the prerequisites for building grpc from source, given in the
[installation instructions](../BUILDING.md).
In order to build the grpc command line tool from a fresh clone of the grpc
repository, you need to run the following command to update submodules:
@ -58,10 +65,13 @@ https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc
Most `grpc_cli` commands need the server to support server reflection. See
guides for
[Java](https://github.com/grpc/grpc-java/blob/master/documentation/server-reflection-tutorial.md#enable-server-reflection)
, [C++](https://github.com/grpc/grpc/blob/master/doc/server_reflection_tutorial.md)
and [Go](https://github.com/grpc/grpc-go/blob/master/Documentation/server-reflection-tutorial.md)
,
[C++](https://github.com/grpc/grpc/blob/master/doc/server_reflection_tutorial.md)
and
[Go](https://github.com/grpc/grpc-go/blob/master/Documentation/server-reflection-tutorial.md)
Local proto files can be used as an alternative. See instructions [below](#Call-a-remote-method).
Local proto files can be used as an alternative. See instructions
[below](#Call-a-remote-method).
## Usage
@ -176,8 +186,8 @@ We can send RPCs to a server and get responses using `grpc_cli call` command.
```
If the proto file is not under the current directory, you can use
`--proto_path` to specify new search roots
(separated by colon on Mac/Linux/Cygwin or semicolon on Windows).
`--proto_path` to specify new search roots (separated by colon on
Mac/Linux/Cygwin or semicolon on Windows).
Note that the tool will always attempt to use the reflection service first,
falling back to local proto files if the service is not found. Use

@ -4,6 +4,10 @@
proposed how gRPC supports TCP-level proxies via the HTTP CONNECT request,
defined in [RFC-2817](https://www.rfc-editor.org/rfc/rfc2817).
This guide documents gRPC C-Core's default proxy mapper implementation.
## HTTP Proxy
**Case 1** in the proposal documents a use-case where all outbound traffic from
an environment must go through a proxy. Configurations for such environments are
usually performed using environment variables such as `http_proxy`. gRPC
@ -11,11 +15,7 @@ supports this by providing a default proxy mapper implementation that allows for
overriding the server name (provided in the channel creation hostname) to
resolve based on such configurations.
This guide documents gRPC C-Core's default proxy mapper implementation.
## Working
### Enabling HTTP Proxy
### Enabling the HTTP Proxy
C-Core checks the following places to determine the HTTP proxy to use, stopping
at the first one that is set:
@ -65,3 +65,24 @@ addresses as the host between the range `10.10.0.0` to `10.10.0.255`.
The lookup and subsequent usage of an HTTP proxy for a specific channel can also
be disabled by setting the channel arg `GRPC_ARG_ENABLE_HTTP_PROXY` to 0.
## Address Proxy
**Case 2** in the proposal documents a partially protected environment, where
access to certain addresses must go through a proxy. Name resolution
of protected servers works normally, and the proxy allows the CONNECT request
to use an IP address instead of a hostname.
Only requests for certain hosts must go through the proxy. Requests to other
servers work without the proxy. Custom logic is used to determine which hosts
the proxy will be used for.
To use the address proxy, both of the following parameters need to be specified:
1. Address of the proxy can be specified using `GRPC_ARG_ADDRESS_HTTP_PROXY`
channel argument or `GRPC_ADDRESS_HTTP_PROXY` environment variable. Value of
the channel argument is preferred if both values are specified.
1. Comma-separated list of IP addresses and/or CIDR blocks that should be
accessed through the proxy. This can be specified using
the `GRPC_ARG_ADDRESS_HTTP_PROXY_ENABLED_ADDRESSES` channel argument
or `GRPC_ADDRESS_HTTP_PROXY_ENABLED_ADDRESSES` environment variable. Value of
the channel argument is preferred if both values are specified.

@ -69,6 +69,7 @@ some configuration as environment variables that can be set.
- health_check_client - traces health checking client code
- http - traces state in the http2 transport engine
- http2_stream_state - traces all http2 stream state mutations.
- http2_ping - traces pings/ping acks/antagonist writes in http2 stack.
- http1 - traces HTTP/1.x operations performed by gRPC
- inproc - traces the in-process transport
- http_keepalive - traces gRPC keepalive pings
@ -101,7 +102,6 @@ some configuration as environment variables that can be set.
- xds_client - traces xds client
- xds_cluster_manager_lb - traces cluster manager LB policy
- xds_cluster_impl_lb - traces cluster impl LB policy
- xds_cluster_resolver_lb - traces xds cluster resolver LB policy
- xds_resolver - traces xds resolver
The following tracers will only run in binaries built in DEBUG mode. This is

@ -58,4 +58,8 @@
- 1.56 'g' stands for ['galvanized'](https://github.com/grpc/grpc/tree/v1.56.x)
- 1.57 'g' stands for ['grounded'](https://github.com/grpc/grpc/tree/v1.57.x)
- 1.58 'g' stands for ['goku'](https://github.com/grpc/grpc/tree/v1.58.x)
- 1.59 'g' stands for ['generative'](https://github.com/grpc/grpc/tree/master)
- 1.59 'g' stands for ['generative'](https://github.com/grpc/grpc/tree/v1.59.x)
- 1.60 'g' stands for ['gjallarhorn'](https://github.com/grpc/grpc/tree/v1.60.x)
- 1.61 'g' stands for ['grand'](https://github.com/grpc/grpc/tree/v1.61.x)
- 1.62 'g' stands for ['guardian'](https://github.com/grpc/grpc/tree/v1.62.x)
- 1.63 'g' stands for ['giggle'](https://github.com/grpc/grpc/tree/master)

@ -58,18 +58,20 @@ Features | gRFCs | [C++, Python,<br> Ruby, PHP](https://github.com/grpc/grpc/re
Request matching based on:<ul><li>[Path](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch) (prefix, full path and safe regex)</li><ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routematch) must be true else config is NACKed</li></ul><li>[Headers](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-headermatcher)</li></ul>Request routing to multiple clusters based on [weights](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-weightedcluster) | [A28](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) | v1.31.0 | v1.31.0 | v1.31.0 | v1.3.0 |
Case insensitive prefix/full path matching:<ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routematch) can be true or false</li></ul> | | v1.34.0 | v1.34.0 | v1.34.0 | v1.3.0 |
Support for [xDS v3 APIs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/api) | [A30](https://github.com/grpc/proposal/blob/master/A30-xds-v3.md) | v1.36.0 | v1.36.0 | v1.36.0 | v1.4.0 |
Support for [xDS v2 APIs](https://www.envoyproxy.io/docs/envoy/latest/api/api_supported_versions) | [A27](https://github.com/grpc/proposal/blob/master/A30-xds-v3.md#details-of-the-v2-to-v3-transition) | < v1.51.0 | < v1.53.0 | TBA | < v1.8.0 |
Support for [xDS v2 APIs](https://www.envoyproxy.io/docs/envoy/latest/api/api_supported_versions) | [A27](https://github.com/grpc/proposal/blob/master/A30-xds-v3.md#details-of-the-v2-to-v3-transition) | < v1.51.0 | < v1.53.0 | < v1.54.0 | < v1.8.0 |
[Maximum Stream Duration](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routeaction-maxstreamduration):<ul><li>Only max_stream_duration is supported.</li></ul> | [A31](https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md) | v1.37.1 | v1.37.1 | v1.37.0 | v1.4.0 |
[Circuit Breaking](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto):<ul><li>Only max_requests is supported.</li></ul> | [A32](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) | v1.37.1 (N/A for PHP) | v1.37.1 | v1.37.0 | v1.4.0 |
[Fault Injection](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/fault/v3/fault.proto):<br> Only the following fields are supported:<ul><li>delay</li><li>abort</li><li>max_active_faults</li><li>headers</li></ul> | [A33](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) | v1.37.1 | v1.37.1 | v1.37.0 | v1.4.0 |
[Client Status Discovery Service](https://github.com/envoyproxy/envoy/blob/main/api/envoy/service/status/v3/csds.proto) | [A40](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) | v1.37.1 (C++)<br>v1.38.0 (Python) | v1.37.1 | v1.37.0 | v1.5.0 |
[Aggregate Clusters](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/aggregate_cluster.html) and [Logical DNS Clusters](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/service_discovery.html#logical-dns) | [A37](https://github.com/grpc/proposal/blob/master/A37-xds-aggregate-and-logical-dns-clusters.md) | v1.47.0 | v1.39.0 | v1.52.2 | v1.9.0 |
[Ring hash](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#ring-hash) load balancing policy:<br> Only the following [policy specifiers](https://github.com/envoyproxy/envoy/blob/2443032526cf6e50d63d35770df9473dd0460fc0/api/envoy/config/route/v3/route_components.proto#L706) are supported:<ul><li>header</li><li>filter_state with key `io.grpc.channel_id`</li></ul>Only [`XX_HASH`](https://github.com/envoyproxy/envoy/blob/2443032526cf6e50d63d35770df9473dd0460fc0/api/envoy/config/cluster/v3/cluster.proto#L383) function is supported. | [A42](https://github.com/grpc/proposal/blob/master/A42-xds-ring-hash-lb-policy.md) | v1.40.0<br>(C++ and Python) | v1.40.1 | 1.41.0 | |
[Retry](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-retrypolicy):<br>Only the following fields are supported:<ul><li>retry_on for the following conditions: cancelled, deadline-exceeded, internal, resource-exhausted, and unavailable.</li><li>num_retries</li><li>retry_back_off</li></ul> | [A44](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md) | v1.40.0<br>(C++ and Python) | v1.40.1 | 1.41.0 | |
[Retry](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-retrypolicy):<br>Only the following fields are supported:<ul><li>retry_on for the following conditions: cancelled, deadline-exceeded, internal, resource-exhausted, and unavailable.</li><li>num_retries</li><li>retry_back_off</li></ul> | [A44](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md) | v1.40.0<br>(C++ and Python) | v1.40.1 | 1.41.0 | v1.8.0 |
[Security](https://www.envoyproxy.io/docs/envoy/latest/configuration/security/security):<br>Uses [certificate providers](https://github.com/grpc/proposal/blob/master/A29-xds-tls-security.md#certificate-provider-plugin-framework) instead of SDS | [A29](https://github.com/grpc/proposal/blob/master/A29-xds-tls-security.md) | v1.41.0<br>(C++ and Python) | v1.41.0 | 1.41.0 | |
[Authorization (RBAC)](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/rbac/v3/rbac.proto):<br><ul><li>`LOG` action has no effect<li>CEL unsupported and rejected</ul> | [A41](https://github.com/grpc/proposal/blob/master/A41-xds-rbac.md) | v1.51.0<br>(C++ and Python) | v1.42.0 | 1.42.0 | |
[Outlier Detection](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/outlier):<br>Only the following detection types are supported:<ul><li>Success Rate</li><li>Failure Percentage</li></ul> | [A50](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) | v1.51.0 | v1.49.0 | v1.50.0 | v1.7.0 | |
[Custom Load Balancer Configuration](https://github.com/envoyproxy/envoy/blob/57be3189ffa3372b34e9480d1f02b2d165e49077/api/envoy/config/cluster/v3/cluster.proto#L1208) | [A52](https://github.com/grpc/proposal/blob/master/A52-xds-custom-lb-policies.md) | v1.55.0 | v1.47.0 | | |
[xDS Federation](https://github.com/cncf/xds/blob/main/proposals/TP1-xds-transport-next.md) | [A47](https://github.com/grpc/proposal/blob/master/A47-xds-federation.md) | v1.55.0 | | | |
[Client-Side Weighted Round Robin LB Policy](https://github.com/envoyproxy/envoy/blob/a6d46b6ac4750720eec9a49abe701f0df9bf8e0a/api/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto#L36) | [A58](https://github.com/grpc/proposal/blob/master/A58-client-side-weighted-round-robin-lb-policy.md) | v1.55.0 | | | |
[StringMatcher for Header Matching](https://github.com/envoyproxy/envoy/blob/3fe4b8d335fa339ef6f17325c8d31f87ade7bb1a/api/envoy/config/route/v3/route_components.proto#L2280) | [A63](https://github.com/grpc/proposal/blob/master/A63-xds-string-matcher-in-header-matching.md) | v1.56.0 | | | |
[Least Request LB Policy](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers.html#weighted-least-request) | [A48](https://github.com/grpc/proposal/blob/master/A48-xds-least-request-lb-policy.md) | | v1.48.0 | | |
[Outlier Detection](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/outlier):<br>Only the following detection types are supported:<ul><li>Success Rate</li><li>Failure Percentage</li></ul> | [A50](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) | v1.51.0 | v1.49.0 | v1.50.0 | v1.7.0 |
[Custom Load Balancer Configuration](https://github.com/envoyproxy/envoy/blob/57be3189ffa3372b34e9480d1f02b2d165e49077/api/envoy/config/cluster/v3/cluster.proto#L1208) | [A52](https://github.com/grpc/proposal/blob/master/A52-xds-custom-lb-policies.md) | v1.55.0 | v1.47.0 | v1.56.0 | |
[xDS Federation](https://github.com/cncf/xds/blob/main/proposals/TP1-xds-transport-next.md) | [A47](https://github.com/grpc/proposal/blob/master/A47-xds-federation.md) | v1.55.0 | v1.55.0 | v1.55.0 | |
[Client-Side Weighted Round Robin LB Policy](https://github.com/envoyproxy/envoy/blob/a6d46b6ac4750720eec9a49abe701f0df9bf8e0a/api/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto#L36) | [A58](https://github.com/grpc/proposal/blob/master/A58-client-side-weighted-round-robin-lb-policy.md) | v1.55.0 | v1.54.0 | v1.56.0 | |
[StringMatcher for Header Matching](https://github.com/envoyproxy/envoy/blob/3fe4b8d335fa339ef6f17325c8d31f87ade7bb1a/api/envoy/config/route/v3/route_components.proto#L2280) | [A63](https://github.com/grpc/proposal/blob/master/A63-xds-string-matcher-in-header-matching.md) | v1.56.0 | v1.53.0 | v1.56.0 | v1.9.0 |
mTLS Credentials in xDS Bootstrap File | [A65](https://github.com/grpc/proposal/blob/master/A65-xds-mtls-creds-in-bootstrap.md) | v1.57.0 | | | |

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

@ -54,7 +54,7 @@ is working properly by using the [`grpc_cli` command line tool]:
Server Reflection can be used by clients to get information about gRPC services
at runtime. We've provided a descriptor database called
[ProtoReflectionDescriptorDatabase](../../src/python/grpcio_reflection/v1alpha/proto_reflection_descriptor_database.h)
[ProtoReflectionDescriptorDatabase](../../src/python/grpcio_reflection/grpc_reflection/v1alpha/proto_reflection_descriptor_database.py)
which implements the
[DescriptorDatabase](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_database.html#google.protobuf.descriptor_database.DescriptorDatabase)
interface. It manages the communication between clients and reflection services

@ -107,4 +107,4 @@ todo_include_todos = True
# -- Options for substitutions -----------------------------------------------
rst_epilog = '.. |grpc_types_link| replace:: https://github.com/grpc/grpc/blob/%s/include/grpc/impl/codegen/grpc_types.h' % branch
rst_epilog = '.. |channel_arg_names_link| replace:: https://github.com/grpc/grpc/blob/%s/include/grpc/impl/channel_arg_names.h' % branch

@ -45,6 +45,7 @@ Glossary
server object. Channel arguments are meant for advanced usages and contain
experimental API (some may not labeled as experimental). Full list of
available channel arguments and documentation can be found under the
"grpc_arg_keys" section of "grpc_types.h" header file (|grpc_types_link|).
For example, if you want to disable TCP port reuse, you may construct
channel arguments like: ``options = (('grpc.so_reuseport', 0),)``.
"grpc_arg_keys" section of "channel_arg_names.h" header file
(|channel_arg_names_link|). For example, if you want to disable TCP port
reuse, you may construct channel arguments like:
``options = (('grpc.so_reuseport', 0),)``.

@ -0,0 +1,7 @@
gRPC Python Observability
=========================
Module Contents
---------------
.. automodule:: grpc_observability

@ -18,6 +18,7 @@ API Reference
grpc_reflection
grpc_status
grpc_testing
grpc_observability
glossary

@ -23,8 +23,8 @@ We want to be able to answer the following queries:
Specifically, what are the names of the methods, are those methods unary or
streaming, and what are the types of the argument and result?
The first proposed version of the protocol is here:
https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto
The first version of the protocol is here:
https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1/reflection.proto
Note that a server is under no obligation to return a complete list of all
methods it supports. For example, a reverse proxy may support server reflection

@ -62,12 +62,12 @@ DNS](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md).
Here is an example service config in protobuf form:
```
```textproto
{
// Use round_robin LB policy.
# Use round_robin LB policy.
load_balancing_config: { round_robin: {} }
// This method config applies to method "foo/bar" and to all methods
// of service "baz".
# This method config applies to method "foo/bar" and to all methods
# of service "baz".
method_config: {
name: {
service: "foo"
@ -76,7 +76,7 @@ Here is an example service config in protobuf form:
name: {
service: "baz"
}
// Default timeout for matching methods.
# Default timeout for matching methods.
timeout: {
seconds: 1
nanos: 1
@ -87,7 +87,7 @@ Here is an example service config in protobuf form:
Here is the same example service config in JSON form:
```
```json
{
"loadBalancingConfig": [ { "round_robin": {} } ],
"methodConfig": [

@ -24,8 +24,10 @@ statuses are defined as such:
| UNAUTHENTICATED | 16 | The request does not have valid authentication credentials for the operation. |
All RPCs started at a client return a `status` object composed of an integer
`code` and a string `message`. The server-side can choose the status it
returns for a given RPC.
`code` and a string `message`. The server-side can choose the status it returns
for a given RPC. Applications should only use values defined above. gRPC libraries
that encounter values outside this range must either propagate them directly or
convert them to UNKNOWN.
The gRPC client and server-side implementations may also generate and
return `status` on their own when errors happen. Only a subset of

@ -22,7 +22,7 @@ In addition, when handling requests, if the initial request metadata contains th
- If the value matches `sleep-<int>`, the server should wait the specified number of seconds before resuming behavior matching and RPC processing.
- If the value matches `keep-open`, the server should never respond to the request and behavior matching ends.
- If the value matches `error-code-<int>`, the server should respond with the specified status code and behavior matching ends.
- If the value matches `success-on-retry-attempt-<int>`, and the value of the `grpc-previous-rpc-attempts` metadata field is equal to the specified number, the normal RPC processing should resume and behavior matching ends.
- If the value matches `succeed-on-retry-attempt-<int>`, and the value of the `grpc-previous-rpc-attempts` metadata field is equal to the specified number, the normal RPC processing should resume and behavior matching ends.
- A value can have a prefix `hostname=<string>` followed by a space. In that case, the rest of the value should only be applied if the specified hostname matches the server's hostname.
The `rpc-behavior` header value can have multiple options separated by commas. In that case, the value should be split by commas and the options should be applied in the order specified. If a request has multiple `rpc-behavior` metadata values, each one should be processed that way in order.

@ -31,6 +31,7 @@ android {
arguments '-Dhelloworld_GRPC_CPP_PLUGIN_EXECUTABLE=' + grpc_cpp_plugin
arguments '-Dprotobuf_INSTALL=OFF'
arguments '-Dutf8_range_ENABLE_INSTALL=OFF'
version "3.22.1"
}
}
ndk.abiFilters 'x86'
@ -47,6 +48,7 @@ android {
externalNativeBuild {
cmake {
path "CMakeLists.txt"
version "3.22.1"
}
}
}

@ -51,6 +51,7 @@ if(GRPC_AS_SUBMODULE)
# this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_ORCA_SERVICE grpcpp_orca_service)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()

@ -22,7 +22,7 @@ RUN ln -s /usr/bin/python3 /usr/bin/python
RUN mkdir /artifacts
COPY . .
RUN OVERRIDE_BAZEL_VERSION=5.4.0 tools/bazel build //examples/cpp/csm:csm_greeter_client
RUN tools/bazel build //examples/cpp/csm:csm_greeter_client
RUN cp -rL /workdir/bazel-bin/examples/cpp/csm/csm_greeter_client /artifacts/
FROM python:3.9-slim-bookworm

@ -6,6 +6,30 @@ This CSM example builds on the [Hello World Example](https://github.com/grpc/grp
The client takes the following command-line arguments -
* target - By default, the client tries to connect to the xDS "xds:///helloworld:50051" and gRPC would use xDS to resolve this target and connect to the server backend. This can be overriden to change the target.
* cookie_name - session affinity cookie name. Defaults to "GSSA"
* delay_s - delay (in seconds) between the RPCs. Default value is 5
The server takes the following command-line arguments -
* port - Port on which the Hello World service is run. Defaults to 50051.
## Building
From the gRPC workspace folder:
Client:
```
docker build -f examples/cpp/csm/Dockerfile.client
```
Server:
```
docker build -f examples/cpp/csm/Dockerfile.server
```
To push to a registry, add a tag to the image either by adding a `-t` flag to `docker build` command above or run:
```
docker image tag ${sha from build command above} ${tag}
```
And then push the tagged image using `docker push`

@ -16,15 +16,20 @@
*
*/
#include <sys/types.h>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/types/optional.h"
#include "opentelemetry/exporters/prometheus/exporter_factory.h"
#include "opentelemetry/exporters/prometheus/exporter_options.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
@ -40,6 +45,8 @@
#endif
ABSL_FLAG(std::string, target, "xds:///helloworld:50051", "Target string");
ABSL_FLAG(std::string, cookie_name, "GSSA", "Cookie name");
ABSL_FLAG(uint, delay_s, 5, "Delay between requests");
using grpc::Channel;
using grpc::ClientContext;
@ -48,15 +55,13 @@ using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
namespace {
struct Cookie {
std::string name;
std::string value;
std::set<std::string> attributes;
std::pair<std::string, std::string> Header() const {
return std::make_pair("cookie", absl::StrFormat("%s=%s", name, value));
}
template <typename Sink>
friend void AbslStringify(Sink& sink, const Cookie& cookie) {
absl::Format(&sink, "(Cookie: %s, value: %s, attributes: {%s})",
@ -65,49 +70,45 @@ struct Cookie {
}
};
class GreeterClient {
protected:
static Cookie ParseCookie(absl::string_view header) {
Cookie cookie;
std::pair<absl::string_view, absl::string_view> name_value =
absl::StrSplit(header, absl::MaxSplits('=', 1));
cookie.name = std::string(name_value.first);
std::pair<absl::string_view, absl::string_view> value_attrs =
absl::StrSplit(name_value.second, absl::MaxSplits(';', 1));
cookie.value = std::string(value_attrs.first);
for (absl::string_view segment : absl::StrSplit(value_attrs.second, ';')) {
cookie.attributes.emplace(absl::StripAsciiWhitespace(segment));
}
return cookie;
Cookie ParseCookie(absl::string_view header) {
Cookie cookie;
std::pair<absl::string_view, absl::string_view> name_value =
absl::StrSplit(header, absl::MaxSplits('=', 1));
cookie.name = std::string(name_value.first);
std::pair<absl::string_view, absl::string_view> value_attrs =
absl::StrSplit(name_value.second, absl::MaxSplits(';', 1));
cookie.value = std::string(value_attrs.first);
for (absl::string_view segment : absl::StrSplit(value_attrs.second, ';')) {
cookie.attributes.emplace(absl::StripAsciiWhitespace(segment));
}
return cookie;
}
static std::vector<Cookie> GetCookies(
const std::multimap<grpc::string_ref, grpc::string_ref>&
server_initial_metadata,
absl::string_view cookie_name) {
std::vector<Cookie> values;
auto pair = server_initial_metadata.equal_range("set-cookie");
for (auto it = pair.first; it != pair.second; ++it) {
gpr_log(GPR_INFO, "set-cookie header: %s", it->second.data());
const auto cookie = ParseCookie(it->second.data());
if (cookie.name == cookie_name) {
values.emplace_back(cookie);
}
std::vector<Cookie> GetCookies(
const std::multimap<grpc::string_ref, grpc::string_ref>& initial_metadata,
absl::string_view cookie_name) {
std::vector<Cookie> values;
auto pair = initial_metadata.equal_range("set-cookie");
for (auto it = pair.first; it != pair.second; ++it) {
const auto cookie = ParseCookie(it->second.data());
if (cookie.name == cookie_name) {
values.emplace_back(std::move(cookie));
}
return values;
}
return values;
}
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
GreeterClient(std::shared_ptr<Channel> channel, absl::string_view cookie_name)
: stub_(Greeter::NewStub(channel)), cookie_name_(cookie_name) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user, Cookie* cookieFromServer,
const Cookie* cookieToServer) {
void SayHello() {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
request.set_name("world");
// Container for the data we expect from the server.
HelloReply reply;
@ -119,59 +120,45 @@ class GreeterClient {
// The actual RPC.
std::mutex mu;
std::condition_variable cv;
bool done = false;
Status status;
if (cookieToServer != NULL) {
std::pair<std::string, std::string> cookieHeader =
cookieToServer->Header();
context.AddMetadata(cookieHeader.first, cookieHeader.second);
absl::optional<Status> status;
// Set the cookie header if we already got a cookie from the server
if (cookie_from_server_.has_value()) {
context.AddMetadata("cookie",
absl::StrFormat("%s=%s", cookie_from_server_->name,
cookie_from_server_->value));
}
stub_->async()->SayHello(&context, &request, &reply,
[&mu, &cv, &done, &status](Status s) {
status = std::move(s);
std::lock_guard<std::mutex> lock(mu);
done = true;
cv.notify_one();
});
std::unique_lock<std::mutex> lock(mu);
while (!done) {
stub_->async()->SayHello(&context, &request, &reply, [&](Status s) {
std::lock_guard<std::mutex> lock(mu);
status = std::move(s);
cv.notify_one();
});
while (!status.has_value()) {
cv.wait(lock);
}
// Act upon its status.
if (status.ok()) {
if (cookieFromServer != NULL) {
const std::multimap<grpc::string_ref, grpc::string_ref>&
server_initial_metadata = context.GetServerInitialMetadata();
std::vector<Cookie> cookies =
GetCookies(server_initial_metadata, "GSSA");
if (!cookies.empty()) {
*cookieFromServer = cookies.front();
}
}
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
if (!status->ok()) {
std::cout << "RPC failed" << status->error_code() << ": "
<< status->error_message() << std::endl;
return;
}
const std::multimap<grpc::string_ref, grpc::string_ref>&
server_initial_metadata = context.GetServerInitialMetadata();
// Update a cookie after a successful request
std::vector<Cookie> cookies =
GetCookies(server_initial_metadata, cookie_name_);
if (!cookies.empty()) {
cookie_from_server_.emplace(std::move(cookies.front()));
}
std::cout << "Greeter received: " << reply.message() << std::endl;
}
private:
std::unique_ptr<Greeter::Stub> stub_;
std::string cookie_name_;
absl::optional<Cookie> cookie_from_server_;
};
static void sayHello(GreeterClient& greeter, Cookie* cookieFromServer,
const Cookie* cookieToServer) {
std::string user("world");
std::string reply = greeter.SayHello(user, cookieFromServer, cookieToServer);
std::cout << "Greeter received: " << reply << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
absl::StatusOr<grpc::CsmObservability> InitializeObservability() {
opentelemetry::exporter::metrics::PrometheusExporterOptions opts;
// default was "localhost:9464" which causes connection issue across GKE pods
opts.url = "0.0.0.0:9464";
@ -180,21 +167,29 @@ int main(int argc, char** argv) {
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
meter_provider->AddMetricReader(std::move(prometheus_exporter));
auto observability = grpc::experimental::CsmObservabilityBuilder()
.SetMeterProvider(std::move(meter_provider))
.BuildAndRegister();
return grpc::CsmObservabilityBuilder()
.SetMeterProvider(std::move(meter_provider))
.BuildAndRegister();
}
} // namespace
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Setup the observability
auto observability = InitializeObservability();
if (!observability.ok()) {
std::cerr << "CsmObservability::Init() failed: "
<< observability.status().ToString() << std::endl;
return static_cast<int>(observability.status().code());
}
GreeterClient greeter(grpc::CreateChannel(
absl::GetFlag(FLAGS_target), grpc::InsecureChannelCredentials()));
Cookie session_cookie;
sayHello(greeter, &session_cookie, NULL);
GreeterClient greeter(grpc::CreateChannel(absl::GetFlag(FLAGS_target),
grpc::InsecureChannelCredentials()),
absl::GetFlag(FLAGS_cookie_name));
while (true) {
sayHello(greeter, NULL, &session_cookie);
greeter.SayHello();
std::this_thread::sleep_for(
std::chrono::seconds(absl::GetFlag(FLAGS_delay_s)));
}
return 0;
}

@ -108,7 +108,7 @@ int main(int argc, char** argv) {
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
meter_provider->AddMetricReader(std::move(prometheus_exporter));
auto observability = grpc::experimental::CsmObservabilityBuilder()
auto observability = grpc::CsmObservabilityBuilder()
.SetMeterProvider(std::move(meter_provider))
.BuildAndRegister();
if (!observability.ok()) {

@ -0,0 +1,39 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "client",
srcs = ["client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
],
)
cc_binary(
name = "server",
srcs = ["server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
],
)

@ -0,0 +1,70 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building this example.
cmake_minimum_required(VERSION 3.8)
project(Deadline C CXX)
include(../cmake/common.cmake)
# Proto files
get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# hw_grpc_proto
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
target_link_libraries(hw_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
# Targets greeter_(client|server)
foreach(_target
client server)
add_executable(${_target} "${_target}.cc")
target_link_libraries(${_target}
hw_grpc_proto
absl::flags
absl::flags_parse
absl::strings
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
endforeach()

@ -0,0 +1,35 @@
# Deadline Example
## Overview
This example shows you how to use deadline when calling calls.
### Try it!
Once you have working gRPC, you can build this example using either bazel or cmake.
Run the server, which will listen on port 50051:
```sh
$ ./server
```
Run the client (in a different terminal):
```sh
$ ./client
```
To simulate the test scenario, the test server implements following functionalities:
- Response Delay: The server intentionally delays its response for `delay` request messages to induce timeout conditions.
- Deadline Propagation: Upon receiving a request with the `[propagate me]` prefix, the server forwards it back to itselt.
This simulates the propagation of deadlines within the system.
If things go smoothly, you will see the client output:
```
[Successful request] wanted = 0, got = 0
[Exceeds deadline] wanted = 4, got = 4
[Successful request with propagated deadline] wanted = 0, got = 0
[Exceeds propagated deadline] wanted = 4, got = 4
```

@ -0,0 +1,106 @@
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_cat.h"
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::StatusCode;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
void unaryCall(std::shared_ptr<Channel> channel, std::string label,
std::string message, grpc::StatusCode expected_code) {
std::unique_ptr<Greeter::Stub> stub = Greeter::NewStub(channel);
// Data we are sending to the server.
HelloRequest request;
request.set_name(message);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// Set 1 second timeout
context.set_deadline(std::chrono::system_clock::now() +
std::chrono::seconds(1));
// The actual RPC.
std::mutex mu;
std::condition_variable cv;
bool done = false;
Status status;
stub->async()->SayHello(&context, &request, &reply,
[&mu, &cv, &done, &status](Status s) {
status = std::move(s);
std::lock_guard<std::mutex> lock(mu);
done = true;
cv.notify_one();
});
std::unique_lock<std::mutex> lock(mu);
while (!done) {
cv.wait(lock);
}
// Act upon its status.
std::cout << "[" << label << "] wanted = " << expected_code
<< ", got = " << status.error_code() << std::endl;
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
std::string target_str = absl::GetFlag(FLAGS_target);
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
std::shared_ptr<Channel> channel =
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials());
// Making test calls
unaryCall(channel, "Successful request", "world", grpc::StatusCode::OK);
unaryCall(channel, "Exceeds deadline", "delay",
grpc::StatusCode::DEADLINE_EXCEEDED);
unaryCall(channel, "Successful request with propagated deadline",
"[propagate me]world", grpc::StatusCode::OK);
unaryCall(channel, "Exceeds propagated deadline",
"[propagate me][propagate me]world",
grpc::StatusCode::DEADLINE_EXCEEDED);
return 0;
}

@ -0,0 +1,130 @@
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/match.h"
#include "absl/strings/str_format.h"
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
using grpc::CallbackServerContext;
using grpc::Channel;
using grpc::ClientContext;
using grpc::Server;
using grpc::ServerBidiReactor;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic behind the server's behavior.
class GreeterServiceImpl final : public Greeter::CallbackService {
public:
GreeterServiceImpl(const std::string& self_address) {
self_channel_ =
grpc::CreateChannel(self_address, grpc::InsecureChannelCredentials());
}
private:
ServerUnaryReactor* SayHello(CallbackServerContext* context,
const HelloRequest* request,
HelloReply* reply) override {
if (absl::StartsWith(request->name(), "[propagate me]")) {
std::unique_ptr<Greeter::Stub> stub = Greeter::NewStub(self_channel_);
std::this_thread::sleep_for(std::chrono::milliseconds(800));
// Forwarding this call to the self as a different call
HelloRequest new_request;
new_request.set_name(request->name().substr(14));
std::unique_ptr<ClientContext> new_context =
ClientContext::FromCallbackServerContext(*context);
std::mutex mu;
std::condition_variable cv;
bool done = false;
Status status;
stub->async()->SayHello(new_context.get(), &new_request, reply,
[&mu, &cv, &done, &status](Status s) {
status = std::move(s);
std::lock_guard<std::mutex> lock(mu);
done = true;
cv.notify_one();
});
std::unique_lock<std::mutex> lock(mu);
while (!done) {
cv.wait(lock);
}
ServerUnaryReactor* reactor = context->DefaultReactor();
reactor->Finish(status);
return reactor;
}
if (request->name() == "delay") {
// Intentionally delay for 1.5 seconds so that
// the client will see deadline_exceeded.
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}
reply->set_message(request->name());
ServerUnaryReactor* reactor = context->DefaultReactor();
reactor->Finish(Status::OK);
return reactor;
}
std::shared_ptr<Channel> self_channel_;
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
GreeterServiceImpl service(server_address);
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

@ -0,0 +1,42 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "crashing_greeter_client",
srcs = ["crashing_greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
],
)
cc_binary(
name = "greeter_callback_server_admin",
srcs = ["greeter_callback_server_admin.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//:grpc++_reflection",
"//:grpcpp_admin",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/strings:str_format",
],
)

@ -0,0 +1,132 @@
# gRPC C++ Debugging Example
This example demonstrates a handful of ways you can debug your gRPC C++ applications.
## Enabling Trace Logs
gRPC allows you to configure more detailed log output for various aspects of gRPC behavior. The tracing log generation might have a large overhead and result in significantly larger log file sizes, especially when you try to trace transport or timer_check. But it is a powerful tool in your debugging toolkit.
### The Most Verbose Logging
Specify environment variables, then run your application:
```
GRPC_VERBOSITY=debug
GRPC_TRACE=all
```
For more granularity, please see
[environment_variables](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md).
### Debug Transport Protocol
```
GRPC_VERBOSITY=debug
GRPC_TRACE=tcp,http,secure_endpoint,transport_security
```
### Debug Connection Behavior
```
GRPC_VERBOSITY=debug
GRPC_TRACE=call_error,connectivity_state,pick_first,round_robin,glb
```
## GDB and other debuggers
`gdb` (and the like) are tools that lets you inspect your application while it is running, view stack traces on exceptions, pause and step through code at specified points or under certain conditions, etc. See https://www.sourceware.org/gdb/
### Inspecting errors
```
bazel build --config=dbg examples/cpp/debugging:crashing_greeter_client
gdb -ex run \
--args ./bazel-bin/examples/cpp/debugging/crashing_greeter_client \
--crash_on_errors=true \
--target=localhork:50051
```
Once the exception is thrown, you can use `bt` to see the stack trace and examine the crash, `info threads` to get the set of threads, etc. See the [GDB documentation](https://sourceware.org/gdb/current/onlinedocs/gdb.html/) for a more complete list of available features and commands.
### Breaking inside a function
After building the application above, this will break inside gRPC generated stub code:
```
gdb -ex 'b helloworld::Greeter::Stub::SayHello' \
-ex run \
--args ./bazel-bin/examples/cpp/debugging/crashing_greeter_client \
--crash_on_errors=true \
--target=localhork:50051
```
## gRPC Admin Interface: Live Channel Tracing
The [gRPC Admin Service](https://github.com/grpc/proposal/blob/master/A38-admin-interface-api.md)
provides a convenient API in each gRPC language to improve the usability of
creating a gRPC server with admin services to expose states in the gRPC library.
This includes channelz, which is a channel tracing feature; it tracks statistics
like how many messages have been sent, how many of them failed, what are the
connected sockets. See the [Channelz design doc](https://github.com/grpc/proposal/blob/master/A14-channelz.md).
### Integrating the gRPC Admin Service Into Your Server
As seen in the `greeter_callback_admin_server` target, you canenable admin services by using the `AddAdminServices` method.
```
grpc::ServerBuilder builder;
grpc::AddAdminServices(&builder);
builder.AddListeningPort(":50051", grpc::ServerCredentials(...));
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
```
### Using grpcdebug
grpcdebug is a tool created to access the metrics from channelz and health services.
#### Installing the grpcdebug tool
The source code is located in a github project
[grpc-ecosystem/grpcdebug](https://github.com/grpc-ecosystem/grpcdebug). You
can either download [the latest built version]
(https://github.com/grpc-ecosystem/grpcdebug/releases/latest) (recommended) or
follow the README.md to build it yourself.
#### Running the grpcdebug tool
##### Usage
`grpcdebug <target address> [flags] channelz <command> [argument]`
| Command | Argument | Description |
| :--------- | :------------------: | :------------------------------------------------ |
| channel | \<channel id or URL> | Display channel states in a human readable way. |
| channels | | Lists client channels for the target application. |
| server | \<server ID> | Displays server state in a human readable way. |
| servers | | Lists servers in a human readable way. |
| socket | \<socket ID> | Displays socket states in a human readable way. |
| subchannel | \<id> | Display subchannel states in human readable way. |
Generally, you will start with either `servers` or `channels` and then work down
to the details
##### Getting overall server info
To begin with, build and run the server binary in the background
```
bazel build --config=dbg examples/cpp/debugging:all
./bazel-bin/examples/cpp/debugging/greeter_callback_server_admin&
```
You can then inspect the server
```bash
grpcdebug localhost:50051 channelz servers
```
This will show you the server ids with their activity
```text
Server ID Listen Addresses Calls(Started/Succeeded/Failed) Last Call Started
1 [[::]:50051] 38/34/3 now
```
For more information about `grpcdebug` features, please see [the grpcdebug documentation](https://github.com/grpc-ecosystem/grpcdebug)

@ -0,0 +1,92 @@
// Copyright 2023 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(bool, crash_on_errors, false,
"Crash the application on client errors");
ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
// Act upon the status of the actual RPC.
if (absl::GetFlag(FLAGS_crash_on_errors)) {
assert(status.ok());
}
if (status.ok()) {
return reply.message();
} else {
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
GreeterClient greeter(grpc::CreateChannel(
absl::GetFlag(FLAGS_target), grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}

@ -0,0 +1,86 @@
// Copyright 2023 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include <grpcpp/ext/admin_services.h>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
using grpc::CallbackServerContext;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::CallbackService {
ServerUnaryReactor* SayHello(CallbackServerContext* context,
const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
ServerUnaryReactor* reactor = context->DefaultReactor();
reactor->Finish(Status::OK);
return reactor;
}
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Enable gRPC Admin Services
grpc::AddAdminServices(&builder);
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

@ -0,0 +1,40 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "greeter_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
],
)
cc_binary(
name = "greeter_server",
srcs = ["greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/strings:str_format",
],
)

@ -0,0 +1,70 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# cmake build file for C++ helloworld example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building helloworld.
cmake_minimum_required(VERSION 3.8)
project(GenericAPI C CXX)
include(../cmake/common.cmake)
# Proto files
get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
# Include generated *.pb.h files
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# hw_grpc_proto
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
target_link_libraries(hw_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
# Targets greeter_(client|server)
foreach(_target
greeter_client greeter_server)
add_executable(${_target} "${_target}.cc")
target_link_libraries(${_target}
hw_grpc_proto
absl::flags
absl::flags_parse
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
endforeach()

@ -0,0 +1,36 @@
# Generic API Example
## Overview
While generated stub code is often the simpler and best choice for sending and handling API calls,
generic APIs offer unique advantages in specific scenarios, such as proxy implementation.
Their ability to manage multiple message types with a single function makes them particularly handy
in these cases. This example demonstrates how to use generic APIs to achieve this flexibility.
This example implements `greeter_callback_client` and `greeter_callback_server` using the generic APIs.
Therefore, looking at the difference would be helpful to understand how to use generic APIs.
### Try it!
Once you have working gRPC, you can build this example using either bazel or cmake.
Run the server, which will listen on port 50051:
```sh
$ ./greeter_server
```
Run the client (in a different terminal):
```sh
$ ./greeter_client
```
If things go smoothly, you will see the client output:
```
### Send: SayHello(name=World)
Ok. ReplyMessage=Hello World
### Send: SayHello(name=gRPC)
Ok. ReplyMessage=Hello gRPC
```

@ -0,0 +1,112 @@
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include <grpcpp/generic/generic_stub.h>
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
using ProtoGenericStub =
::grpc::TemplatedGenericStub<::google::protobuf::Message,
::google::protobuf::Message>;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(new ProtoGenericStub(channel)) {}
// Assembles the client's payload, sends it and prints the response back
// from the server.
void SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
std::mutex mu;
std::condition_variable cv;
bool done = false;
Status status;
std::cout << absl::StrFormat("### Send: SayHello(name=%s)", user)
<< std::endl;
// Send a unary call using a generic stub. Unlike generated subs,
// this requires to specify the name of call.
stub_->UnaryCall(&context, "/helloworld.Greeter/SayHello",
grpc::StubOptions(), &request, &reply, [&](Status s) {
status = std::move(s);
std::lock_guard<std::mutex> lock(mu);
done = true;
cv.notify_one();
});
std::unique_lock<std::mutex> lock(mu);
while (!done) {
cv.wait(lock);
}
// Handles the reply
if (status.ok()) {
std::cout << absl::StrFormat("Ok. ReplyMessage=%s", reply.message())
<< std::endl;
} else {
std::cout << absl::StrFormat("Failed. Code=%d Message=%s",
status.error_code(), status.error_message())
<< std::endl;
}
}
private:
// Instead of `Greeter::Stub`, it uses `ProtoGenericStub` to send any calls.
std::unique_ptr<ProtoGenericStub> stub_;
};
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
std::string target_str = absl::GetFlag(FLAGS_target);
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
GreeterClient greeter(
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));
greeter.SayHello("World");
greeter.SayHello("gRPC");
return 0;
}

@ -0,0 +1,143 @@
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
#include <memory>
#include <string>
#include <unordered_set>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
using grpc::ByteBuffer;
using grpc::CallbackGenericService;
using grpc::CallbackServerContext;
using grpc::GenericCallbackServerContext;
using grpc::ProtoBufferReader;
using grpc::ProtoBufferWriter;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerGenericBidiReactor;
using grpc::Status;
using grpc::StatusCode;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public CallbackGenericService {
ServerGenericBidiReactor* CreateReactor(
GenericCallbackServerContext* context) override {
if (context->method() == "/helloworld.Greeter/SayHello") {
// Let the SayHello reactor handle this now on.
return new SayHelloReactor();
} else {
// Forward this to the implementation of the base calss returning
// UNIMPLEMENTED.
return CallbackGenericService::CreateReactor(context);
}
}
class SayHelloReactor : public ServerGenericBidiReactor {
public:
SayHelloReactor() { StartRead(&request_); }
private:
Status OnSayHello(const HelloRequest& request, HelloReply* reply) {
if (request.name() == "") {
return Status(StatusCode::INVALID_ARGUMENT, "name is not specified");
}
reply->set_message(absl::StrFormat("Hello %s", request.name()));
return Status::OK;
}
void OnDone() override { delete this; }
void OnReadDone(bool ok) override {
if (!ok) {
return;
}
Status result;
// Deserialize a request message
HelloRequest request;
result = grpc::GenericDeserialize<ProtoBufferReader, HelloRequest>(
&request_, &request);
if (!result.ok()) {
Finish(result);
return;
}
// Call the SayHello handler
HelloReply reply;
result = OnSayHello(request, &reply);
if (!result.ok()) {
Finish(result);
return;
}
// Serialize a reply message
bool own_buffer;
result = grpc::GenericSerialize<ProtoBufferWriter, HelloReply>(
reply, &response_, &own_buffer);
if (!result.ok()) {
Finish(result);
return;
}
StartWrite(&response_);
}
void OnWriteDone(bool ok) override {
Finish(ok ? Status::OK
: Status(StatusCode::UNKNOWN, "Unexpected failure"));
}
ByteBuffer request_;
ByteBuffer response_;
};
private:
absl::Mutex mu_;
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterCallbackGenericService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

@ -0,0 +1,29 @@
# Copyright 2023 the gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "orca_server",
srcs = ["orca_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//:grpcpp_orca_service",
"//examples/protos:helloworld_cc_grpc",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/strings:str_format",
],
)

@ -0,0 +1,46 @@
# gRPC Custom Metrics Example
You can find a complete set of instructions for building gRPC and running the
examples in the [C++ Quick Start][].
This example shows how to implement a server that provides custom metrics usable
by custom load balancing policies.
Server needs to be setup with metrics recorder and Orca service for sending
these metrics to a client:
```c++
GreeterServiceImpl service;
// Setup custom metrics recording
auto server_metric_recorder =
grpc::experimental::ServerMetricRecorder::Create();
grpc::experimental::OrcaService orca_service(
server_metric_recorder.get(),
grpc::experimental::OrcaService::Options().set_min_report_duration(
absl::Seconds(0.1)));
builder.RegisterService(&orca_service);
grpc::ServerBuilder::experimental_type(&builder).EnableCallMetricRecording(
nullptr);
```
Afterwards per-request metrics can be reported from the gRPC service
implementation using the metric recorder from the request context:
```c++
auto recorder = context->ExperimentalGetCallMetricRecorder();
if (recorder == nullptr) {
return Status(grpc::StatusCode::INTERNAL,
"Unable to access metrics recorder. Make sure "
"EnableCallMetricRecording had been called.");
}
recorder->RecordCpuUtilizationMetric(0.5);
```
Out of band metrics can be reported using the `server_metric_recorder`
directly:
```c++
server_metric_recorder->SetCpuUtilization(0.75);
```
[C++ Quick Start]: https://grpc.io/docs/languages/cpp/quickstart

@ -0,0 +1,101 @@
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include "examples/protos/helloworld.grpc.pb.h"
#include <grpcpp/ext/call_metric_recorder.h>
#include <grpcpp/ext/orca_service.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/support/status.h>
using grpc::CallbackServerContext;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerUnaryReactor;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
ABSL_FLAG(uint16_t, port, 50051, "Server port for the service");
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::CallbackService {
ServerUnaryReactor* SayHello(CallbackServerContext* context,
const HelloRequest* request,
HelloReply* reply) override {
ServerUnaryReactor* reactor = context->DefaultReactor();
// Obtain the call metric recorder and use it to report the number of
// DB queries (custom cost metric) and CPU utilization.
auto recorder = context->ExperimentalGetCallMetricRecorder();
if (recorder == nullptr) {
reactor->Finish({grpc::StatusCode::INTERNAL,
"Unable to access metrics recorder. Make sure "
"EnableCallMetricRecording had been called."});
return reactor;
}
recorder->RecordRequestCostMetric("db_queries", 10);
recorder->RecordCpuUtilizationMetric(0.5);
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
reactor->Finish(Status::OK);
return reactor;
}
};
void RunServer(uint16_t port) {
std::string server_address = absl::StrFormat("0.0.0.0:%d", port);
ServerBuilder builder;
GreeterServiceImpl service;
// Setup custom metrics recording. Note that this recorder may be use to send
// the out-of-band metrics to the client.
auto server_metric_recorder =
grpc::experimental::ServerMetricRecorder::Create();
grpc::experimental::OrcaService orca_service(
server_metric_recorder.get(),
grpc::experimental::OrcaService::Options().set_min_report_duration(
absl::Seconds(0.1)));
builder.RegisterService(&orca_service);
grpc::ServerBuilder::experimental_type(&builder).EnableCallMetricRecording(
server_metric_recorder.get());
// Resume setting up gRPC server as usual
grpc::EnableDefaultHealthCheckService(true);
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save