diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a9806c --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Hugo default output directory +/public +/resources + +## OS Files +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ + +# OSX +.DS_Store +*~ diff --git a/Makefile b/Makefile index bdce879..2e0a08c 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,16 @@ +HUGO_VERSION = 0.53 +DOCKER_IMG := klakegg/hugo:$(HUGO_VERSION) +SERVE_CMD = server --buildDrafts --buildFuture --disableFastRender --ignoreCache + serve: hugo server \ --buildDrafts \ --buildFuture \ --disableFastRender +docker-serve: + docker run --rm -it -v $(CURDIR):/src -p 1313:1313 $(DOCKER_IMG) $(SERVE_CMD) + production-build: hugo \ --minify @@ -13,4 +20,4 @@ preview-build: --baseURL $(DEPLOY_PRIME_URL) \ --buildDrafts \ --buildFuture \ - --minify + --minify \ No newline at end of file diff --git a/README.md b/README.md index c7179d9..baa3695 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,25 @@ -# gRPC -This is the new [gRPC](https://grpc.io/) website, written on [Hugo](https://gohugo.io/). Here are a few key things to know about the site: -* Key variables are stored in `/config.toml`, for example `grpc_release_tag` which is used in various places throughout the site. -* If you're not familiar with Hugo, all content is stored in the `/content` directory. Go there to edit anything on the site. Images are stored in `/static/img`. Check out the [Hugo Quick Start](https://gohugo.io/getting-started/quick-start/) for a quick intro to Hugo. +# The gRPC website and documentation + +This repository houses the assets used to build and deploy the gRPC website, available at https://grpc.io. The site is built using the [Hugo](https://gohugo.io) static site generator. Check out the [Hugo Quick Start](https://gohugo.io/getting-started/quick-start/) for a quick intro. + +## Running the site locally + +To run the site locally, you need to [install Hugo](https://gohugo.io/getting-started/installing). Once Hugo is installed: + +```bash +make serve +``` + +Alternatively, you can run the site using a [Docker](https://docker.com) container: + +```bash +make docker-serve +``` + +## Publishing the site + +The gRPC website is automatically published by [Netlify](https://netlify.com). Any time changes are pushed to the `master` branch, the site is re-built and re-deployed. This process does not require manual management. + +## Site content + +All of the [Markdown](https://www.markdownguide.org/) content used to build the site's documentation, blog, etc. is in the [`content`](./content) directory. \ No newline at end of file diff --git a/config.toml b/config.toml index 6d71d29..dc4d88e 100644 --- a/config.toml +++ b/config.toml @@ -9,6 +9,7 @@ grpc_release_tag_no_v = "1.20.0" grpc_java_release_tag = "v1.20.0" milestones_link = "https://github.com/grpc/grpc/milestones" +# Configuration required for auto-generating the Netlify _redirects file [mediaTypes."text/netlify"] delimiter = "" diff --git a/content/docs/guides/auth.md b/content/docs/guides/auth.md index 1781c86..2c11cce 100644 --- a/content/docs/guides/auth.md +++ b/content/docs/guides/auth.md @@ -1,7 +1,6 @@ --- layout: guides title: Authentication -aliases: [/docs/guides/auth.html] ---

This document provides an overview of gRPC authentication, including our built-in supported auth mechanisms, how to plug in your own diff --git a/content/docs/guides/benchmarking.md b/content/docs/guides/benchmarking.md index b9aa351..9c31820 100644 --- a/content/docs/guides/benchmarking.md +++ b/content/docs/guides/benchmarking.md @@ -1,7 +1,6 @@ --- layout: guides title: Benchmarking -aliases: [/docs/guides/benchmarking.html] ---

gRPC is designed to support high-performance open-source RPCs in many languages. This document describes the diff --git a/content/docs/guides/concepts.md b/content/docs/guides/concepts.md index 6e1149b..2ead78c 100644 --- a/content/docs/guides/concepts.md +++ b/content/docs/guides/concepts.md @@ -1,7 +1,6 @@ --- layout: guides title: gRPC Concepts -aliases: [/docs/guides/concepts.html] ---

This document introduces some key gRPC concepts with an overview of gRPC's architecture and RPC life cycle.

diff --git a/content/docs/guides/error.md b/content/docs/guides/error.md index ee473ec..ae2d1f3 100644 --- a/content/docs/guides/error.md +++ b/content/docs/guides/error.md @@ -1,7 +1,6 @@ --- layout: guides title: Error Handling -aliases: [/docs/guides/error.html] ---

This page describes how gRPC deals with errors, including gRPC's built-in error codes. Example code in different languages can be found here.

diff --git a/content/docs/quickstart/android.md b/content/docs/quickstart/android.md index 2ce503d..d7d198b 100644 --- a/content/docs/quickstart/android.md +++ b/content/docs/quickstart/android.md @@ -1,7 +1,7 @@ --- layout: quickstart title: Android Java Quickstart -aliases: [/docs/quickstart/android.html] +short: Android ---

This guide gets you started with gRPC in Android Java with a simple working example.

diff --git a/content/docs/quickstart/cpp.md b/content/docs/quickstart/cpp.md index c1e6b2c..489b22e 100644 --- a/content/docs/quickstart/cpp.md +++ b/content/docs/quickstart/cpp.md @@ -1,7 +1,7 @@ --- layout: quickstart -title: C++ Quickstart -aliases: [/docs/quickstart/cpp.html] +title: C++ Quick Start +short: C++ ---

This guide gets you started with gRPC in C++ with a simple working example.

@@ -225,28 +225,30 @@ int main(int argc, char** argv) { Just like we did before, from the `examples/cpp/helloworld` directory: 1. Build the client and server after having made changes: - ```sh - $ make - ``` + + ```sh + $ make + ``` 2. Run the server - ```sh - $ ./greeter_server - ``` + ```sh + $ ./greeter_server + ``` 3. On a different terminal, run the client - ```sh - $ ./greeter_client - ``` + ```sh + $ ./greeter_client + ``` - You should see the updated output: - ```sh - $ ./greeter_client - Greeter received: Hello world - Greeter received: Hello again world - ``` + You should see the updated output: + + ```sh + $ ./greeter_client + Greeter received: Hello world + Greeter received: Hello again world + ``` ### What's next diff --git a/content/docs/quickstart/csharp.md b/content/docs/quickstart/csharp.md index b95d7bb..526199c 100644 --- a/content/docs/quickstart/csharp.md +++ b/content/docs/quickstart/csharp.md @@ -1,7 +1,7 @@ --- title: C# Quick Start layout: quickstart -aliases: [/docs/quickstart/csharp.html] +short: C# ---

This guide gets you started with gRPC in C# with a simple diff --git a/content/docs/quickstart/dart.md b/content/docs/quickstart/dart.md index 2de3281..8346909 100644 --- a/content/docs/quickstart/dart.md +++ b/content/docs/quickstart/dart.md @@ -1,7 +1,7 @@ --- layout: quickstart title: Dart Quickstart -aliases: [/docs/quickstart/dart.html] +short: Dart ---

This guide gets you started with gRPC in Dart with a simple working example.

diff --git a/content/docs/quickstart/go.md b/content/docs/quickstart/go.md index 8f0f044..da23196 100644 --- a/content/docs/quickstart/go.md +++ b/content/docs/quickstart/go.md @@ -1,7 +1,7 @@ --- title: Go Quick Start layout: quickstart -aliases: [/docs/quickstart/go.html] +short: Go ---

This guide gets you started with gRPC in Go with a simple working example.

diff --git a/content/docs/quickstart/java.md b/content/docs/quickstart/java.md index fabf89e..c2f03cb 100644 --- a/content/docs/quickstart/java.md +++ b/content/docs/quickstart/java.md @@ -1,7 +1,7 @@ --- layout: quickstart -title: Java Quickstart -aliases: [/docs/quickstart/java.html] +title: Java Quick Start +short: Java ---

This guide gets you started with gRPC in Java with a simple working example.

diff --git a/content/docs/quickstart/node.md b/content/docs/quickstart/node.md index 7608f8c..5c68e60 100644 --- a/content/docs/quickstart/node.md +++ b/content/docs/quickstart/node.md @@ -1,7 +1,7 @@ --- title: Node Quick Start layout: quickstart -aliases: [/docs/quickstart/node.html] +short: Node ---

This guide gets you started with gRPC in Node with a simple working example.

diff --git a/content/docs/quickstart/objective-c.md b/content/docs/quickstart/objective-c.md index 9112c17..4d90674 100644 --- a/content/docs/quickstart/objective-c.md +++ b/content/docs/quickstart/objective-c.md @@ -1,7 +1,7 @@ --- layout: quickstart -title: Objective-C Quickstart -aliases: [/docs/quickstart/objective-c.html] +title: Objective-C Quick Start +short: Objective-C ---

This guide gets you started with gRPC on the iOS platform in Objective-C with a simple working example.

diff --git a/content/docs/quickstart/php.md b/content/docs/quickstart/php.md index b6d4c70..5387ec6 100644 --- a/content/docs/quickstart/php.md +++ b/content/docs/quickstart/php.md @@ -1,7 +1,7 @@ --- layout: quickstart -title: PHP Quickstart -aliases: [/docs/quickstart/php.html] +title: PHP Quick Start +short: PHP ---

This guide gets you started with gRPC in PHP with a simple working example.

diff --git a/content/docs/quickstart/python.md b/content/docs/quickstart/python.md index 2834136..e178d9f 100644 --- a/content/docs/quickstart/python.md +++ b/content/docs/quickstart/python.md @@ -1,7 +1,7 @@ --- layout: quickstart -title: Python Quickstart -aliases: [/docs/quickstart/python.html] +title: Python Quick Start +short: Python ---

This guide gets you started with gRPC in Python with a simple working example.

diff --git a/content/docs/quickstart/ruby.md b/content/docs/quickstart/ruby.md index 7ea4150..08c68d8 100644 --- a/content/docs/quickstart/ruby.md +++ b/content/docs/quickstart/ruby.md @@ -1,7 +1,7 @@ --- title: Ruby Quick Start layout: quickstart -aliases: [/docs/quickstart/ruby.html] +short: Ruby ---

This guide gets you started with gRPC in Ruby with a simple diff --git a/content/docs/quickstart/web.md b/content/docs/quickstart/web.md index 657202b..70e6ebe 100644 --- a/content/docs/quickstart/web.md +++ b/content/docs/quickstart/web.md @@ -1,7 +1,7 @@ --- title: Web Quick Start layout: quickstart -aliases: [/docs/quickstart/web.html] +short: Web ---

This guide gets you started with gRPC-Web with a simple working example from the browser.

diff --git a/content/docs/reference/go/generated-code.md b/content/docs/reference/go/generated-code.md index ba53f5d..d3d2bb3 100644 --- a/content/docs/reference/go/generated-code.md +++ b/content/docs/reference/go/generated-code.md @@ -2,7 +2,6 @@ bodyclass: docs headline: Go Generated Code Reference layout: docs -aliases: [/docs/reference/go/generated-code.html] --- # Go Generated Code Reference diff --git a/content/docs/reference/java/generated-code.md b/content/docs/reference/java/generated-code.md index 9625798..85d47d2 100644 --- a/content/docs/reference/java/generated-code.md +++ b/content/docs/reference/java/generated-code.md @@ -2,7 +2,6 @@ bodyclass: docs title: Java Generated Code Reference layout: docs -aliases: [/docs/reference/java/generated-code.html] --- # Java Generated Code Reference diff --git a/content/docs/reference/python/generated-code.md b/content/docs/reference/python/generated-code.md index 6af256d..3e2b42b 100644 --- a/content/docs/reference/python/generated-code.md +++ b/content/docs/reference/python/generated-code.md @@ -2,7 +2,6 @@ bodyclass: docs layout: docs headline: Python Generated Code Reference -aliases: [/docs/reference/python/generated-code.html] --- # Python Generated Code Reference diff --git a/content/docs/tutorials/async/helloasync-cpp.md b/content/docs/tutorials/async/helloasync-cpp.md index afa1fc4..6618f0b 100644 --- a/content/docs/tutorials/async/helloasync-cpp.md +++ b/content/docs/tutorials/async/helloasync-cpp.md @@ -1,7 +1,8 @@ --- layout: tutorials title: Asynchronous Basics - C++ -aliases: [docs/tutorials/async/helloasync-cpp.html] +short: Async - C++ +group: async --- This tutorial shows you how to write a simple server and client in C++ using diff --git a/content/docs/tutorials/auth/oauth2-objective-c.md b/content/docs/tutorials/auth/oauth2-objective-c.md index dc59e28..af6813d 100644 --- a/content/docs/tutorials/auth/oauth2-objective-c.md +++ b/content/docs/tutorials/auth/oauth2-objective-c.md @@ -1,8 +1,10 @@ --- layout: tutorials title: OAuth2 on gRPC - Objective-C -aliases: [/docs/tutorials/auth/oauth2-objective-c.html] +short: Auth - Objective-C +group: auth --- + This example demonstrates how to use OAuth2 on gRPC to make authenticated API calls on behalf of a user. diff --git a/content/docs/tutorials/basic/android.md b/content/docs/tutorials/basic/android.md index 6291fbf..7004a12 100644 --- a/content/docs/tutorials/basic/android.md +++ b/content/docs/tutorials/basic/android.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Android Java -aliases: [/docs/tutorials/basic/android.html] +short: Android +group: basic --- This tutorial provides a basic Android Java programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/c.md b/content/docs/tutorials/basic/c.md index 63ed6b6..165ced2 100644 --- a/content/docs/tutorials/basic/c.md +++ b/content/docs/tutorials/basic/c.md @@ -1,8 +1,10 @@ --- layout: tutorials -title: gRPC Basics - C++ -aliases: [/docs/tutorials/basic/c.html] +title: gRPC Basics - C++ +group: basic +short: C --- + This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: diff --git a/content/docs/tutorials/basic/csharp.md b/content/docs/tutorials/basic/csharp.md index 3ac695f..d34039f 100644 --- a/content/docs/tutorials/basic/csharp.md +++ b/content/docs/tutorials/basic/csharp.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - C# -aliases: [/docs/tutorials/basic/csharp.html] +group: basic +short: C# --- This tutorial provides a basic C# programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/dart.md b/content/docs/tutorials/basic/dart.md index adcad2a..8a400ff 100644 --- a/content/docs/tutorials/basic/dart.md +++ b/content/docs/tutorials/basic/dart.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Dart -aliases: [/docs/tutorials/basic/dart.html] +group: basic +short: Dart --- This tutorial provides a basic Dart programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/go.md b/content/docs/tutorials/basic/go.md index 7cfea7a..15b8507 100644 --- a/content/docs/tutorials/basic/go.md +++ b/content/docs/tutorials/basic/go.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Go -aliases: [/docs/tutorials/basic/go.html] +group: basic +short: Go --- This tutorial provides a basic Go programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/java.md b/content/docs/tutorials/basic/java.md index 0284d2a..83e2c18 100644 --- a/content/docs/tutorials/basic/java.md +++ b/content/docs/tutorials/basic/java.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Java -aliases: [/docs/tutorials/basic/java.html] +group: basic +short: Java --- This tutorial provides a basic Java programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/node.md b/content/docs/tutorials/basic/node.md index a05d82f..309afd3 100644 --- a/content/docs/tutorials/basic/node.md +++ b/content/docs/tutorials/basic/node.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Node.js -aliases: [/docs/tutorials/basic/node.html] +group: basic +short: Node --- This tutorial provides a basic Node.js programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/objective-c.md b/content/docs/tutorials/basic/objective-c.md index d8f4fdf..9993bdb 100644 --- a/content/docs/tutorials/basic/objective-c.md +++ b/content/docs/tutorials/basic/objective-c.md @@ -1,7 +1,7 @@ --- layout: tutorials title: gRPC Basics - Objective-C -aliases: [/docs/tutorials/basic/objective-c.html] +group: basic --- This tutorial provides a basic Objective-C programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/php.md b/content/docs/tutorials/basic/php.md index 69d2562..92e27fd 100644 --- a/content/docs/tutorials/basic/php.md +++ b/content/docs/tutorials/basic/php.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - PHP -aliases: [/docs/tutorials/basic/php.html] +group: basic +short: PHP --- This tutorial provides a basic PHP programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/python.md b/content/docs/tutorials/basic/python.md index 52d11b7..28505be 100644 --- a/content/docs/tutorials/basic/python.md +++ b/content/docs/tutorials/basic/python.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Python -aliases: [/docs/tutorials/basic/python.html] +group: basic +short: Python --- This tutorial provides a basic Python programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/ruby.md b/content/docs/tutorials/basic/ruby.md index a697e1a..1f0e1b1 100644 --- a/content/docs/tutorials/basic/ruby.md +++ b/content/docs/tutorials/basic/ruby.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Ruby -aliases: [/docs/tutorials/basic/ruby.html] +group: basic +short: Ruby --- This tutorial provides a basic Ruby programmer's introduction to working with gRPC. diff --git a/content/docs/tutorials/basic/web.md b/content/docs/tutorials/basic/web.md index 2d9d2a8..ac46c41 100644 --- a/content/docs/tutorials/basic/web.md +++ b/content/docs/tutorials/basic/web.md @@ -1,7 +1,8 @@ --- layout: tutorials title: gRPC Basics - Web -aliases: [/docs/tutorials/basic/web.html] +group: basic +short: Web --- This tutorial provides a basic introduction on how to use diff --git a/data/redirects.yaml b/data/redirects.yaml index 818b227..b511373 100644 --- a/data/redirects.yaml +++ b/data/redirects.yaml @@ -1,3 +1,4 @@ +splat: - go - java - python diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 6ade1c3..d0668c5 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -11,14 +11,13 @@ {{ block "title" . }}{{ .Site.Title }}{{ end }} - - + + + + - - - - + diff --git a/layouts/docs/quickstart.html b/layouts/docs/quickstart.html index 5e8359e..30cab2c 100644 --- a/layouts/docs/quickstart.html +++ b/layouts/docs/quickstart.html @@ -1,8 +1,12 @@ {{ define "title" }} - {{ .Title }} – {{ .Site.Title }} +{{ .Title }} – {{ .Site.Title }} {{ end }} + {{ define "main" }} +{{ $currentUrl := .RelPermalink }} +{{ $quickstartDocs := where site.Pages ".Layout" "quickstart" }} +
Documentation
@@ -14,19 +18,19 @@
-Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web + Quick Start + + + Quick Start Home + + + {{ range $quickstartDocs }} + {{ $isCurrentPage := eq $currentUrl .RelPermalink }} + {{ $title := .Params.short }} + + {{ $title }} + + {{ end }}
diff --git a/layouts/docs/tutorials.html b/layouts/docs/tutorials.html index 0d712fb..c6c878d 100644 --- a/layouts/docs/tutorials.html +++ b/layouts/docs/tutorials.html @@ -3,6 +3,12 @@ {{ .Title }} – {{ .Site.Title }} {{ end }} {{ define "main" }} +{{ $currentUrl := .RelPermalink }} +{{ $tutorials := where site.Pages ".Layout" "tutorials" }} +{{ $async := where $tutorials ".Params.group" "eq" "async" }} +{{ $auth := where $tutorials ".Params.group" "eq" "auth" }} +{{ $basic := where $tutorials ".Params.group" "eq" "basic" }} +
Documentation
@@ -15,21 +21,32 @@
Tutorials -Async - C++ -Auth - Objective C + +{{ range $auth }} +{{ $isCurrentPage := eq $currentUrl .RelPermalink }} +{{ $title := .Params.short }} + + {{ $title }} + +{{ end }} + +{{ range $async }} +{{ $isCurrentPage := eq $currentUrl .RelPermalink }} +{{ $title := .Params.short }} + + {{ $title }} + +{{ end }} + Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web + +{{ range $basic }} +{{ $isCurrentPage := eq $currentUrl .RelPermalink }} +{{ $title := .Params.short }} + + {{ $title }} + +{{ end }}
diff --git a/layouts/index.redirects b/layouts/index.redirects index 5701af9..e0f5e62 100644 --- a/layouts/index.redirects +++ b/layouts/index.redirects @@ -1,4 +1,5 @@ -{{- $redirects := site.Data.redirects -}} -{{- range $redirects -}} -/grpc-{{ . }}/* https://github.com/grpc/grpc-{{ . }}/:splat +{{- $splatRedirects := site.Data.redirects.splat -}} +{{- range $splatRedirects -}} +/grpc-{{ . }}/* https://grpc.github.io/grpc-{{ . }}/:splat {{ end -}} +/grpc/* https://grpc.github.io/grpc/:splat diff --git a/public/_redirects b/public/_redirects deleted file mode 100644 index 84bdbe7..0000000 --- a/public/_redirects +++ /dev/null @@ -1,16 +0,0 @@ -/grpc-go/* https://github.com/grpc/grpc-go/:splat -/grpc-java/* https://github.com/grpc/grpc-java/:splat -/grpc-python/* https://github.com/grpc/grpc-python/:splat -/grpc-dotnet/* https://github.com/grpc/grpc-dotnet/:splat -/grpc-swift/* https://github.com/grpc/grpc-swift/:splat -/grpc-proto/* https://github.com/grpc/grpc-proto/:splat -/grpc-web/* https://github.com/grpc/grpc-web/:splat -/grpc-dart/* https://github.com/grpc/grpc-dart/:splat -/grpc-community/* https://github.com/grpc/grpc-community/:splat -/grpc-node/* https://github.com/grpc/grpc-node/:splat -/grpc-swift/* https://github.com/grpc/grpc-swift/:splat -/grpc-php/* https://github.com/grpc/grpc-php/:splat -/grpc-java-api-checker/* https://github.com/grpc/grpc-java-api-checker/:splat -/grpc-docker-library/* https://github.com/grpc/grpc-docker-library/:splat -/grpc-experiments/* https://github.com/grpc/grpc-experiments/:splat -/grpc-haskell/* https://github.com/grpc/grpc-haskell/:splat diff --git a/public/about/index.html b/public/about/index.html deleted file mode 100644 index fdfb45c..0000000 --- a/public/about/index.html +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - About gRPC – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
About gRPC
-
-
-
- -
- - -

gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.

- -

The main usage scenarios:

- - - -

Core Features that make it awesome:

- - - -
- -

Cases: Who’s using it and why?

- -

Many companies are already using gRPC for connecting multiple services in their environments. The use case varies from connecting a handful of services to hundreds of services across various languages in on-prem or cloud environments. Below are details and quotes from some of our early adopters.

- -

Check out what people are saying below:

- -
-
-
- - -
-
- At Square, we have been collaborating with Google so that we can replace all uses of our custom RPC solution to use gRPC. We decided to move to gRPC because of its open support for multiple platforms, the demonstrated performance of the protocol, and the ability to customize and adapt it to our network. Developers at Square are looking forward to being able to take advantage of writing streaming APIs and in the future, push gRPC to the edges of the network for integration with mobile clients and third party APIs. -
- -

-

- -
- -
-
- In our initial use of gRPC we've been able to extend it easily to live within our opinionated ecosystem. Further, we've had great success making improvements directly to gRPC through pull requests and interactions with Google's team that manages the project. We expect to see many improvements to developer productivity, and the ability to allow development in non-JVM languages as a result of adopting gRPC. -
- -

-
- -
-
- At CoreOS we are excited by the gRPC v1.0 release and the opportunities it opens up for people consuming and building what we like to call Google Infrastructure for Everyone Else. Today gRPC is in use in a number of our critical open source projects such as the etcd consensus database and the rkt container engine. -

- -

-
-
- -
-
- Our switch from a home-grown RPC system to gRPC was seamless. We quickly took advantage of the per-stream flow control to provide better scheduling of large RPCs over the same connection as small ones. -

- -

- -
- -
-
- With support for high performance bi-directional streaming, TLS based security, and a wide variety of programming languages, gRPC is an ideal unified transport protocol for model driven configuration and telemetry. -
- -

- -
- -
-
- Carbon3D uses gRPC to implement distributed processes both within and outside our 3D printers. We actually switched from using Thrift early on for a number of reasons including but not limited to robust support for multiple languages like C++, Nodejs and Python. Features like bi-directional streaming are a huge win in keeping our systems implementations simpler and correct. Lastly the gRPC team/community is very active and responsive which is also a key factor for us in selecting an open source technology for mission critical projects. -
- -

- -
-
-
-
- We've been using gRPC for both classes and research at University of Wisconsin. Students in our distributed systems class (CS 739) utilized many of its powerful features when building their own distributed systems. In addition, gRPC is a key component of our OpenLambda research project (https://www.open-lambda.org/) which aims to provide an open-source, low-latency, serverless computational framework. -
-
- -
- -
-
- The fact that gRPC is built on HTTP/2 transport brings us native bi-directional streaming capabilities and flexible custom-metadata in request headers. The first point is important for large payloadexchange and network telemetry scenarios while the latter enables us to expand and include capabilities including but not limited to various network element authentication mechanisms. - - In addition, the wide language binding support that gRPC/proto3 bringsenables us to provide a flexible and rapid development environment for both internal and external consumers. - - Last but not least, while there are a number of network communicationprotocols for configuration, operational state retrieval and network telemetry, gRPC provides us with a unified flexible protocol and transport to ease client/server interaction. -
- -

- -
-

Officially Supported Platforms

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Language Platform Compiler
C/C++LinuxGCC 4.4
GCC 4.6
GCC 5.3
Clang 3.5
Clang 3.6
Clang 3.7|
C/C++Windows 7+Visual Studio 2013+
C#Windows 7+ Linux
.NET Core, .NET 4.5+
.NET Core, Mono 4+
.NET Core, Mono 4+
DartWindows/Linux/Mac Dart 2.0+
GoWindows/Linux/Mac Go 1.6+
JavaWindows/Linux/Mac JDK 8 recommended. Gingerbread+ for Android
Node.jsWindows/Linux/Mac Node v4+
PHP * Linux/Mac PHP 5.5+ and PHP 7.0+
Python Windows/Linux/Mac Python 2.7 and Python 3.4+
Ruby Windows/Linux/Mac
- - -

The story behind gRPC

-Google has been using a single general-purpose RPC infrastructure called Stubby to connect the large number of microservices running within and across our data centers for over a decade. Our internal systems have long embraced the microservice architecture gaining popularity today. Stubby has powered all of Google’s microservices interconnect for over a decade and is the RPC backbone behind every Google service that you use today. In March 2015, we decided to build the next version of Stubby in the open so we can share our learnings with the industry and collaborate with them to build the next version of Stubby both for microservices inside and outside Google but also for last mile of computing (mobile, web and IOT). -
-For more background on why we created gRPC, read the gRPC Motivation and Design Principles blog. -

-
- -
- - - - - - - - - - diff --git a/public/blog/2017-08-17-community-meeting-update/index.html b/public/blog/2017-08-17-community-meeting-update/index.html deleted file mode 100644 index 642b8c3..0000000 --- a/public/blog/2017-08-17-community-meeting-update/index.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - - - - - 2017-08-17 Community Meeting Update – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

2017-08-17 Community Meeting Update

-
Posted on Thursday, August 17, 2017 - by - - Jaye Pitzeruse - -
-

-

Next Community Meeting: Thursday, August 31, 2017 11am Pacific Time (US and Canada)

- -

General Announcements

- -

Call for Papers: CloudNativeCon

- -

CloudNativeCon gathers all CNCF (Cloud Native Computing Foundation) projects under a single roof. -Presenters will be talking about their experiences with Kubernetes, Prometheus, OpenTracing, Fluentd, Linkerd, gRPC, CoreDNS, containerd, rkt and CNI. -The call for papers period will be ending on Monday, August 21, 2017. -The conference will be taking place on the 6th and 7th of December, 2017. -If you submit a talk, please add an entry to the spreadsheet linked in the gRPC Community Meeting Working Doc.

- -

Register for CloudNativeCon

- -

Release Updates

- -

1.6 will be available soon. -The required changes have already been merged and published in the protocol buffer libraries. -Keep your eyes peeled for the upcoming release.

- -

Platform Updates

- -

No platform updates.

- -

Language Updates

- -

No language specific updates.

-

- - -
- - - - - - - - - - diff --git a/public/blog/2017-08-22-grpc-go-perf-improvements/index.html b/public/blog/2017-08-22-grpc-go-perf-improvements/index.html deleted file mode 100644 index 8f5ec36..0000000 --- a/public/blog/2017-08-22-grpc-go-perf-improvements/index.html +++ /dev/null @@ -1,484 +0,0 @@ - - - - - - - - - - - - 2017-08-22 gRPC-Go performance Improvements – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

2017-08-22 gRPC-Go performance Improvements

-
Posted on Tuesday, August 22, 2017 - by - - Mahak Mukhi - -
-

-

-For past few months we’ve been working on improving gRPC-Go performance. This includes improving network utilization, optimizing CPU usage and memory allocations. Most of our recent effort has been focused around revamping gRPC-Go flow control. After several optimizations and new features we’ve been able to improve quite significantly, especially on high-latency networks. We expect users that are working with high-latency networks and large messages to see an order of magnitude performance gain. -Benchmark results at the end.

- -

This blog summarizes the work we have done so far (in chronological order) to improve performance and lays out our near-future plans. -


- -

Recently Implemented Optimizations

- -
Expanding stream window on receiving large messages
- -

Code link

- -

This is an optimization used by gRPC-C to achieve performance benefits for large messages. The idea is that when there’s an active read by the application on the receive side, we can effectively bypass stream-level flow control to request the whole message. This proves to be very helpful with large messages. Since the application is already committed to reading and has allocated enough memory for it, it makes sense that we send a proactive large window update (if necessary) to get the whole message rather than receiving it in chunks and sending window updates when we run low on window.

- -

This optimization alone provided a 10x improvement for large messages on high-latency networks.

- -
Decoupling application reads from connection flow control
- -

Code link

- -

After having several discussions with gRPC-Java and gRPC-C core team we realized that gRPC-Go’s connection-level flow control was overly restrictive in the sense that window updates on the connection depended upon if the application had read data from it or not. It must be noted that it makes perfect sense to have stream-level flow control depended on application read but not so much for connection-level flow control. The rationale is as follows: A connection is shared by several streams (RPCs). If there were at least one stream that read slowly or didn’t read at all, it would hamper the performance or completely stall other streams on that connection. This happens because we won’t send out window updates on the connection until that slow or inactive stream read data. Therefore, it makes sense to decouple the connection’s flow control from application reads.

- -

However, this begs at least two questions:

- -
    -
  1. Won’t a client be able to send as much data as it wants to the server by creating new streams when one runs out?

  2. - -
  3. Why even have connection-level flow control if the stream-level flow control is enough?

  4. -
- -

The answer to the first question is short and simple: no. A server has an option to limit the number of streams that it intends to serve concurrently. Therefore, although at first it may seem like a problem, it really is not.

- -

The need for connection-level flow control:

- -

It is true that stream-level flow control is sufficient to throttle a sender from sending too much data. But not having connection-level flow control (or using an unlimited connection-level window) makes it so that when things get slower on a stream, opening a new one will appear to make things faster. This will only take one so far since the number of streams are limited. However, having a connection-level flow control window set to the Bandwidth Delay Product (BDP) of the network puts an upper-bound on how much performance can realistically be squeezed out of the network.

- -
Piggyback window updates
- -

Code link

- -

Sending a window update itself has a cost associated to it; a flush operation is necessary, which results in a syscall. Syscalls are blocking and slow. Therefore, when sending out a stream-level window update, it makes sense to also check if a connection-level window update can be sent using the same flush syscall.

- -
BDP estimation and dynamic flow control window
- -

Code link

- -

This feature is the latest and in some ways the most awaited optimization feature that has helped us close the final gap between gRPC and HTTP/1.1 performance on high latency networks.

- -

Bandwidth Delay Product (BDP) is the bandwidth of a network connection times its round-trip latency. This effectively tells us how many bytes can be “on the wire” at a given moment, if full utilization is achieved.

- -

The algorithm to compute BDP and adapt accordingly was first proposed by @ejona and later implemented by both gRPC-C core and gRPC-Java (note that it isn’t enabled in Java yet). The idea is simple and powerful: every time a receiver gets a data frame it sends out a BDP ping (a ping with unique data only used by BDP estimator). After this, the receiver starts counting the number of bytes it receives (including the ones that triggered the BDP ping) until it receives the ack for that ping. This total sum of all bytes received in about 1.5 RTT (Round-Trip Time) is an approximation of the effective BDP * 1.5. If this is close to our current window size (say, more than 2/3rd of it) we must increase the window size. We put our window sizes (both streaming and connection) to be twice the BDP we sampled(total sum of all bytes received).

- -

This algorithm by itself could cause the BDP estimation to increase indefinitely; an increase in window will result in sampling more bytes which in turn will cause the window to be increased further. This phenomenon is called buffer-bloat and was discovered by earlier implementations in gRPC-C core and gRPC-Java. The solution to this is to calculate the bandwidth for every sample and check if it is greater than the maximum bandwidth noted so far. If so, only then increase our window sizes. The bandwidth, as we know, can be calculated by dividing the sample by RTT * 1.5 (remember the sample was for one and a half round trips). If the bandwidth doesn’t increase with an increase in sampled bytes that’s indicative that this change is because of an increased window size and doesn’t really reflect the nature of the network itself.

- -

While running experiments on VMs in different continents we realized that every once in awhile a rogue, unnaturally fast ping-ack at the right time (really the wrong time) would cause our window sizes to go up. This happens because such a ping-ack would cause us to notice a decreased RTT and calculate a high bandwidth value. Now if that sample of bytes was greater than 2/3rd of our window then we would increase the window sizes. However, this ping ack was an aberration and shouldn’t have changed our perception of the network RTT al together. Therefore, we keep a running average of the RTTs we note weighted by a constant rather than the total number of samples to heed more to recent RTTs and less to the ones in past. It is important because networks might change over time.

- -

During implementation, we experimented with several tuning parameters, such as the multiplier to compute the window size from the sample size to select the best settings, that balanced between growth and accuracy.

- -

Given that we’re always bound by the flow control of TCP which for most cases is upper bounded at 4MB, we bound the growth of our window sizes by the same number: 4MB.

- -

BDP estimation and dynamically adjusting window sizes is turned-on by default and can be turned off by setting values manually for connection and/or stream window sizes.

- -
Near-future efforts
- -

We are now looking into improving our throughput by better CPU utilization, the following efforts are in-line with that.

- -
Reducing flush syscalls
- -

We noticed a bug in our transport layer which causes us to make a flush syscall for every data frame we write, even if the same goroutine has more data to send. We can batch a lot of these writes to use only one flush. This in fact will not be a big change to the code itself.

- -

In our efforts to get rid of unnecessary flushes we recently combined the headers and data write for unary and server streaming RPCs to one flush on the client-side. Link to code

- -

Another related idea proposed by one of our users @petermattic in this PR was to combine a server response to a unary RPC into one flush. We are currently looking into that as well.

- -
Reducing memory allocation
- -

For every data frame read from the wire a new memory allocation takes place. The same holds true at the gRPC layer for every new message for decompressing and decoding. These allocations result in excessive garbage collection cycles, which are expensive. Reusing memory buffers can reduce this GC pressure, and we are prototyping approaches to do so. As requests need buffers of differing sizes, one approach would be to maintain individual memory pools of fixed sizes (powers of two). So now when reading x bytes from the wire we can find the nearest power of 2 greater than x and reuse a buffer from our cache if available or allocate a new one if need be. We will be using golang sync Pools so we don’t have to worry about garbage collection. However, we will need to run sufficient tests before committing to this.

- -
Results:
- - - - - - - - - - - - - - -
Message Size GRPC HTTP 1.1
1 KB~152 ms~152 ms
10 KB~152 ms~152 ms
10 KB~152 ms~152 ms
1 MB~152 ms~152 ms
10 MB~622 ms~630 ms
100 MB~5 sec~5 sec
- - - -
No Latency Network
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GRPCHTTP 2.0HTTP 1.1
5.097809ms16.107461ms18.298959ms
4.46083ms4.301808ms7.715456ms
5.081421ms4.076645ms8.118601ms
4.338013ms4.232606ms6.621028ms
5.013544ms4.693488ms5.83375ms
3.963463ms4.558047ms5.571579ms
3.509808ms4.855556ms4.966938ms
4.864618ms4.324159ms6.576279ms
3.545933ms4.61375ms6.105608ms
3.481094ms4.621215ms7.001607ms
- -
Network with RTT of 16ms
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GRPCHTTP 2.0HTTP 1.1
118.837625ms84.453913ms58.858109ms
36.801006ms22.476308ms20.877585ms
35.008349ms21.206222ms19.793881ms
21.153461ms20.940937ms22.18179ms
20.640364ms21.888247ms21.4666ms
21.410346ms21.186008ms20.925514ms
19.755766ms21.818027ms20.553768ms
20.388882ms21.366796ms21.460029ms
20.623342ms20.681414ms20.586908ms
20.452023ms20.781208ms20.278481ms
- -
Network with RTT of 64ms
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GRPCHTTP 2.0HTTP 1.1
455.072669ms275.290241ms208.826314ms
195.43357ms70.386788ms70.042513ms
132.215978ms70.01131ms71.19429ms
69.239273ms70.032237ms69.479335ms
68.669903ms70.192272ms70.858937ms
70.458108ms69.395154ms71.161921ms
68.488057ms69.252731ms71.374758ms
68.816031ms69.628744ms70.141381ms
69.170105ms68.935813ms70.685521ms
68.831608ms69.728349ms69.45605ms
-

- - -
- - - - - - - - - - diff --git a/public/blog/2018-01-22-grpc-go-engineering-practices/index.html b/public/blog/2018-01-22-grpc-go-engineering-practices/index.html deleted file mode 100644 index 956a3f6..0000000 --- a/public/blog/2018-01-22-grpc-go-engineering-practices/index.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - - - - - - - - - 2018-01-19 gRPC-Go Engineering Practices – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

2018-01-19 gRPC-Go Engineering Practices

-
Posted on Monday, January 22, 2018 - by - - Doug Fawley, gRPC-Go TL - -
-

-

It’s the start of the new year, and almost the end of my first full year on the -gRPC-Go project, so I’d like to take this opportunity to provide an update on -the state of gRPC-Go development and give some visibility into how we manage the -project. For me, personally, this is the first open source project to which -I’ve meaningfully contributed, so this year has been a learning experience for -me. Over this year, the team has made constant improvements to our work habits -and communication. I still see room for improvement, but I believe we are in a -considerably better place than we were a year ago.

- -

Repo Health

- -

When I first joined the gRPC-Go team, they had been without their previous -technical lead for a few months. At that time, we had 45 open PRs, the oldest -of which was over a year old at the time. As a new team member and maintainer, -the accumulation of stale PRs made it difficult to assess priorities and -understand the state of things. For our contributors, neglecting PRs was both -disrespectful and an inconvenience when we started asking for rebases due to -other commits. To resolve this, we made a concerted effort to either merge or -close all of those PRs, and we now hold weekly meetings to review the status of -every active PR to prevent the situation from reoccurring.

- -

At the same time, we had 103 open issues, many of which were already fixed or -outdated or untriaged. Since then, we fixed or closed 85 of those and put in -place a process to ensure we triage and prioritize new issues on a weekly -rotation. Similarly to our PRs, we also review our assigned and high-priority -issues in a weekly meeting.

- -

Our ongoing SLO for new issues and PRs is 1 week to triage and first response.

- -

We also revamped our labels for issues -and PRs to help with organization. We typically apply a priority (P0-P3) and a -type (e.g. Bug, Feature, or Performance) to every issue. We also have a -collection of status labels we apply in various situations. The type labels are -also applied to PRs to aid in generating our release notes.

- -

Versioning and Backward Compatibility

- -

We have recently documented our versioning -policy. -Our goal is to maintain full backward compatibility except in limited -circumstances, including experimental APIs and mitigating security risks (most -notably #1392). If you notice a -behavior regression, please don’t hesitate to open an -issue in our repo (please be -reasonable).

- -

gRFC

- -

The gRPC proposal repo contains proposals -for substantial feature changes for gRPC that need to be designed upfront, -called gRFCs. The purpose of this process is to provide visibility and solicit -feedback from the community. Each change is discussed on our mailing -list and debated before the -change is made. We leveraged this before making the -backward-compatibility-breaking metadata change (gRFC -L7), and -also for designing the new resolver/balancer API (gRFC -L9).

- -

Regression Testing

- -

Every PR in our repo must pass our unit and end-to-end tests. Our current test -coverage is 85%. Anytime a regression is identified, we add a test that covers -the failing scenario, both to prove to ourselves that the problem is resolved by -the fix, and to prevent it from reoccurring in the future. This helps us -improve our overall coverage numbers as well. We also intend to re-enable -coverage reporting for all PRs, but in a non-blocking fashion (related -issue).

- -

In addition to testing for correctness, any PR that we suspect will impact -performance is run though our benchmarks. We have a set of benchmarks both in -our open source repo -and also within Google. These comprise a variety of workloads that we believe -are most important for our users, both streaming and unary, and some are -specifically designed to measure our optimal QPS, throughput, or latency.

- -

Releases

- -

The GA release of gRPC-Go was made in conjunction with the other languages in -July of 2016. The team performed several patch releases between then and the -end of 2016, but none included release notes. Our subsequent releases have -improved in regularity (a minor release is performed every six weeks) and -in the quality of the release notes. We also are responsive with patch -releases, back-porting bug fixes to older releases either on demand or for more -serious issues within a week.

- -

When performing a release, in addition to the tests in our repo, we also run a -full suite of inter-op tests with other gRPC language implementations. This -process has been working well for us, and we will cover more about this in a -future blog post.

- -

Non-Open Source Work

- -

We have taken an “open source first” approach to developing gRPC. This means -that, wherever possible, gRPC functionality is added directly into the open -source project. However, to work within Google’s infrastructure, our team -sometimes needs to provide additional functionality on top of gRPC. This is -typically done through hooks like the stats -API or -interceptors -or custom resolvers.

- -

To keep Google’s internal version of gRPC up-to-date with the open source -version, we do weekly or on-demand imports. Before an import, we run every test -within Google that depends upon gRPC. This gives us another way in which we can -catch problems before performing releases in Open Source.

- -

Looking Forward

- -

In 2018, we intend to do more of the same, and maintain our SLOs around -addressing issues and accepting contributions to the project. We also would -like to more aggressively tag issues with the “Help -Wanted” label -for anyone looking to contribute to have a bigger selection of issues to choose -from.

- -

For gRPC itself, one of our main focuses right now is performance, which we hope -will transparently benefit many of our users. In the near-term, we have some -exciting changes we’re wrapping up that should provide a 30+% reduction in -latency with high concurrency, resulting in a QPS improvement of ~25%. Once -that work is done, we have a list of other performance -issues -that we’ll be tackling next.

- -

On user experience, we want to provide better documentation, and are starting to -improve our godoc with better comments and more examples. We want to improve -the overall experience of using gRPC, so we will be working closely on projects -around distributed tracing, monitoring, and testing to make gRPC services easier -to manage in production. We want to do more, and we are hoping that starting -with these and listening to feedback will help us ship improvements steadily.

-

- - -
- - - - - - - - - - diff --git a/public/blog/a_short_introduction_to_channelz/index.html b/public/blog/a_short_introduction_to_channelz/index.html deleted file mode 100644 index 77408d5..0000000 --- a/public/blog/a_short_introduction_to_channelz/index.html +++ /dev/null @@ -1,431 +0,0 @@ - - - - - - - - - - - - A short introduction to Channelz – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

A short introduction to Channelz

-
Posted on Wednesday, September 05, 2018 - by - - Yuxuan Li - -
-

-

Channelz is a tool that provides comprehensive runtime info about connections at -different levels in gRPC. It is designed to help debug live programs, which may -be suffering from network, performance, configuration issues, etc. The -gRFC provides a -detailed explanation of channelz design and is the canonical reference for all -channelz implementations across languages. The purpose of this blog is to -familiarize readers with channelz service and how to use it for debugging -issues. The context of this post is set in -gRPC-Go, but the overall idea should be -applicable across languages. At the time of writing, channelz is available for -gRPC-Go and -gRPC-Java. Support for -C++ and wrapped languages is coming soon.

- -

Let’s learn channelz through a simple example which uses channelz to help debug -an issue. The -helloworld -example from our repo is slightly modified to set up a buggy scenario. You can -find the full source code here: -client, -server.

- -
- -
-

Client setup:

- -

The client will make 100 SayHello RPCs to a specified target and load balance -the workload with the round robin policy. Each call has a 150ms timeout. RPC -responses and errors are logged for debugging purposes.

-
- -
- -

Running the program, we notice in the log that there are intermittent errors -with error code DeadlineExceeded (as shown in Figure 1).

- -

However, there’s no clue about what is causing the deadline exceeded error and -there are many possibilities:

- - - -

- -

Figure 1. Program log -screenshort

- -

Let’s turn on grpc INFO logging for more debug info and see if we can find -something helpful.

- -

- -

Figure 2. -gRPC INFO log

- -

As shown in Figure 2, the info log indicates that all three connections to the -server are connected and ready for transmitting RPCs. No suspicious event shows -up in the log. One thing that can be inferred from the info log is that all -connections are up all the time, therefore the lost connection hypothesis can be -ruled out.

- -

To further narrow down the root cause of the issue, we will ask channelz for -help.

- -

Channelz provides gRPC internal networking machinery stats through a gRPC -service. To enable channelz, users just need to register the channelz service to -a gRPC server in their program and start the server. The code snippet below -shows the API for registering channelz service to a -grpc.Server. Note that this -has already been done for our example client.

-
import "google.golang.org/grpc/channelz/service"
-
-// s is a *grpc.Server
-service.RegisterChannelzServiceToServer(s)
-
-// call s.Serve() to serve channelz service
-

A web tool called -grpc-zpages -has been developed to conveniently serve channelz data through a web page. -First, configure the web app to connect to the gRPC port that’s serving the -channelz service (see instructions from the previous link). Then, open the -channelz web page in the browser. You should see a web page like Figure 3. Now -we can start querying channelz!

- -

- -

- -

Figure 3. -Channelz main page

- -

As the error is on the client side, let’s first click on -TopChannels. -TopChannels is a collection of root channels which don’t have parents. In -gRPC-Go, a top channel is a -ClientConn created by the -user through Dial or -DialContext, and used -for making RPC calls. Top channels are of -Channel -type in channelz, which is an abstraction of a connection that an RPC can be -issued to.

- -

- -

- -

Figure 4. -TopChannels result

- -

So we click on the TopChannels, and a page like Figure 4 appears, which lists -all the live top channel(s) with related info.

- -

As shown in Figure 5, there is only one top channel with id = 2 (Note that text -in square brackets is the reference name of the in memory channel object, which -may vary across languages).

- -

Looking at the Data section, we can see there are 15 calls failed out of 100 -on this channel.

- -

- -

- -

Figure 5. -Top Channel (id = 2)

- -

On the right hand side, it shows the channel has no child Channels, 3 -Subchannels (as highlighted in Figure 6), and 0 Sockets.

- -

- -

- -

Figure 6. -Subchannels owned by the Channel (id = 2)

- -

A -Subchannel -is an abstraction over a connection and used for load balancing. For example, -you want to send requests to “google.com”. The resolver resolves “google.com” to -multiple backend addresses that serve “google.com”. In this example, the client -is set up with the round robin load balancer, so all live backends are sent -equal traffic. Then the (logical) connection to each backend is represented as a -Subchannel. In gRPC-Go, a -SubConn can be seen -as a Subchannel.

- -

The three Subchannels owned by the parent Channel means there are three -connections to three different backends for sending the RPCs to. Let’s look -inside each of them for more info.

- -

So we click on the first Subchannel ID (i.e. “4[]”) listed, and a page like -Figure 7 renders. We can see that all calls on this Subchannel have succeeded. -Thus it’s unlikely this Subchannel is related to the issue we are having.

- -

- -

- -

Figure 7. -Subchannel (id = 4)

- -

So we go back, and click on Subchannel 5 (i.e. “5[]”). Again, the web page -indicates that Subchannel 5 also never had any failed calls.

- -

- -

- -

Figure 8. -Subchannel (id = 6)

- -

And finally, we click on Subchannel 6. This time, there’s something different. -As we can see in Figure 8, there are 15 out of 34 RPC calls failed on this -Subchannel. And remember that the parent Channel also has exactly 15 failed -calls. Therefore, Subchannel 6 is where the issue comes from. The state of the -Subchannel is READY, which means it is connected and is ready to transmit -RPCs. That rules out network connection problems. To dig up more info, let’s -look at the Socket owned by this Subchannel.

- -

A -Socket -is roughly equivalent to a file descriptor, and can be generally regarded as the -TCP connection between two endpoints. In grpc-go, -http2Client -and -http2Server -correspond to Socket. Note that a network listener is also considered a Socket, -and will show up in the channelz Server info.

- -

- -

- -

Figure 9. -Subchannel (id = 6) owns Socket (id = 8)

- -

We click on Socket 8, which is at the bottom of the page (see Figure 9). And we -now see a page like Figure 10.

- -

The page provides comprehensive info about the socket like the security -mechanism in use, stream count, message count, keepalives, flow control numbers, -etc. The socket options info is not shown in the screenshot, as there are a lot -of them and not related to the issue we are investigating.

- -

The Remote Address field suggests that the backend we are having a problem -with is “127.0.0.1:10003”. The stream counts here correspond perfectly to -the call counts of the parent Subchannel. From this, we can know that the server -is not actively sending DeadlineExceeded errors. This is because if the -DeadlineExceeded error is returned by the server, then the streams would all be -successful. A client side stream’s success is independent of whether the call -succeeds. It is determined by whether a HTTP2 frame with EOS bit set has been -received (refer to the -gRFC -for more info). Also, we can see that the number of messages sent is 34, which -equals the number of calls, and it rules out the possibility of the client being -stuck somehow and results in deadline exceeded. In summary, we can narrow down -the issue to the server which serves on 127.0.0.1:10003. It may be that the -server is slow to respond, or some proxy in front of it is dropping requests.

- -

- -

- -

Figure 10. Socket -(id = 8)

- -

As you see, channelz has helped us pinpoint the potential root cause of the -issue with just a few clicks. You can now concentrate on what’s happening with -the pinpointed server. And again, channelz may help expedite the debugging at -the server side too.

- -

We will stop here and let readers explore the server side channelz, which is -simpler than the client side. In channelz, a -Server -is also an RPC entry point like a Channel, where incoming RPCs arrive and get -processed. In grpc-go, a -grpc.Server corresponds to a -channelz Server. Unlike Channel, Server only has Sockets (both listen socket(s) -and normal connected socket(s)) as its children.

- -

Here are some hints for the readers:

- - - -

You should notice that the number of messages received by the server socket is -the same as sent by the client socket (Socket 8), which rules out the case of -having a misbehaving proxy (dropping request) in the middle. And the number of -messages sent by the server socket is equal to the messages received at client -side, which means the server was not able to send back the response before -deadline. You may now look at the -server code -to verify whether it is indeed the cause.

- -
- -
-

Server setup:

- -

The server side program starts up three GreeterServers, with two of them using -an implementation -(server{}) -that imposes no delay when responding to the client, and one using an -implementation -(slowServer{}) -which injects a variable delay of 100ms - 200ms before sending the response.

-
- -
- -

As you can see through this demo, channelz helped us quickly narrow down the -possible causes of an issue and is easy to use. For more resources, see the -detailed channelz -gRFC. Find us on -github at https://github.com/grpc/grpc-go.

-

- - -
- - - - - - - - - - diff --git a/public/blog/bazel_rules_protobuf/index.html b/public/blog/bazel_rules_protobuf/index.html deleted file mode 100644 index 6c86703..0000000 --- a/public/blog/bazel_rules_protobuf/index.html +++ /dev/null @@ -1,1063 +0,0 @@ - - - - - - - - - - - - Building gRPC services with bazel and rules_protobuf – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Building gRPC services with bazel and rules_protobuf

-
Posted on Thursday, October 13, 2016 - by - - Paul Cody Johnston - -
-

-

gRPC makes it easier to build high-performance -microservices by providing generated service entrypoints in a variety -of different languages. Bazel complements these -efforts with a capable and fast polyglot build environment.

- -

rules_protobuf extends -bazel and makes it easier develop gRPC services.

- -

It does this by:

- -
    -
  1. Building protoc (the protocol buffer compiler) and all the -necessary protoc-gen-* plugins.
  2. -
  3. Building the protobuf and gRPC libraries required for gRPC-related -code to compile.
  4. -
  5. Abstracting away protoc plugin invocation (you don’t have to -necessarily learn or remember how to call protoc).
  6. -
  7. Regenerating and recompiling outputs when protobuf source files -change.
  8. -
- -

In this post I’ll provide background about how bazel works -(Part 1) and how to get started building gRPC -services with rules_protobuf -(Part 2). If -you’re already a bazel aficionado, you can skip directly to Part 2.

- -

To best follow along, -install bazel -and clone the rules_protobuf repository:

-
~$ git clone https://github.com/pubref/rules_protobuf
-~$ cd rules_protobuf
-~/rules_protobuf$
-

Great. Let’s get started!

- -

1: About Bazel

- -

Bazel is Google’s open-source version of -their internal build tool called “Blaze”. Blaze originated from the -challenges of managing a large monorepo with code written in a variety -of languages. Blaze was the inspiration for other capable and fast -build tools including Pants and -Buck. Bazel is conceptually simple but -there are some core concepts & terminology to understand:

- -
    -
  1. Bazel command: a function that does some type of work when -called from the command line. Common ones include bazel build -(compile a libary), bazel run (run a binary executable), bazel -test (execute tests), and bazel query (tell me something about -the build dependency graph). See all with bazel help.

  2. - -
  3. Build phases: the three stages (loading, analysis, and -execution) that bazel goes through when calling a bazel command.

  4. - -
  5. The WORKSPACE file: a required file that defines the project -root. It is primarily used to declare external dependencies -(external workspaces).

  6. - -
  7. BUILD files: the presence of a BUILD file in a directory -defines it as a package. BUILD files contain rules that define -targets which can be selected using the target pattern syntax. -Rules are written in a python-like language called -skylark. -Syklark has stronger deterministic guarantees than python but is -intentionally minimal, excluding language features such as recursion, -classes, and lambdas.

  8. -
- -

1.1: Package Structure

- -

To illustrate these concepts, let’s look at the package structure of -the -rules_protobuf examples subdirectory. -Let’s look at the file tree, showing only those folder having a -BUILD file:

-
$ tree -P 'BUILD|WORKSPACE' -I 'third_party|bzl' examples/
-.
-├── BUILD
-├── WORKSPACE
-└── examples
-    ├── helloworld
-    │   ├── cpp
-    │   │   └── BUILD
-    │   ├── go
-    │   │   ├── client
-    │   │   │   └── BUILD
-    │   │   ├── greeter_test
-    │   │   │   └── BUILD
-    │   │   └── server
-    │   │       └── BUILD
-    │   ├── grpc_gateway
-    │   │   └── BUILD
-    │   ├── java
-    │   │   └── org
-    │   │       └── pubref
-    │   │           └── rules_protobuf
-    │   │               └── examples
-    │   │                   └── helloworld
-    │   │                       ├── client
-    │   │                       │   └── BUILD
-    │   │                       └── server
-    │   │                           └── BUILD
-    │   └── proto
-    │       └── BUILD
-    └── proto
-        └── BUILD
-
-

1.2: Targets

- -

To get a list of targets within the examples/ folder, use a query. -This says “Ok bazel, show me all the callable targets in all packages -within the examples folder, and say what kind of thing it is in -addition to its path label”:

-
~/rules_protobuf$ bazel query //examples/... --output label_kind | sort | column -t
-
-cc_binary                   rule  //examples/helloworld/cpp:client
-cc_binary                   rule  //examples/helloworld/cpp:server
-cc_library                  rule  //examples/helloworld/cpp:clientlib
-cc_library                  rule  //examples/helloworld/proto:cpp
-cc_library                  rule  //examples/proto:cpp
-cc_proto_compile            rule  //examples/helloworld/proto:cpp.pb
-cc_proto_compile            rule  //examples/proto:cpp.pb
-cc_test                     rule  //examples/helloworld/cpp:test
-filegroup                   rule  //examples/helloworld/proto:protos
-filegroup                   rule  //examples/proto:protos
-go_binary                   rule  //examples/helloworld/go/client:client
-go_binary                   rule  //examples/helloworld/go/server:server
-go_library                  rule  //examples/helloworld/go/server:greeter
-go_library                  rule  //examples/helloworld/grpc_gateway:gateway
-go_library                  rule  //examples/helloworld/proto:go
-go_library                  rule  //examples/proto:go_default_library
-go_proto_compile            rule  //examples/helloworld/proto:go.pb
-go_proto_compile            rule  //examples/proto:go_default_library.pb
-go_test                     rule  //examples/helloworld/go/greeter_test:greeter_test
-go_test                     rule  //examples/helloworld/grpc_gateway:greeter_test
-grpc_gateway_proto_compile  rule  //examples/helloworld/grpc_gateway:gateway.pb
-java_binary                 rule  //examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/client:netty
-java_binary                 rule  //examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/server:netty
-java_library                rule  //examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/client:client
-java_library                rule  //examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/server:server
-java_library                rule  //examples/helloworld/proto:java
-java_library                rule  //examples/proto:java
-java_proto_compile          rule  //examples/helloworld/proto:java.pb
-java_proto_compile          rule  //examples/proto:java.pb
-js_proto_compile            rule  //examples/helloworld/proto:js
-js_proto_compile            rule  //examples/proto:js
-py_proto_compile            rule  //examples/helloworld/proto:py.pb
-ruby_proto_compile          rule  //examples/proto:rb.pb
-

We’re not limited to targets in our own workspace. As it turns out, -the Google Protobuf repo is -named as an external repository (more on this later) and we can also -address targets in that workspace in the same way. Here’s a partial -list:

-
~/rules_protobuf$ bazel query @com_github_google_protobuf//... --output label_kind | sort | column -t
-
-cc_binary       rule  @com_github_google_protobuf//:protoc
-cc_library      rule  @com_github_google_protobuf//:protobuf
-cc_library      rule  @com_github_google_protobuf//:protobuf_lite
-cc_library      rule  @com_github_google_protobuf//:protoc_lib
-cc_library      rule  @com_github_google_protobuf//util/python:python_headers
-filegroup       rule  @com_github_google_protobuf//:well_known_protos
-java_library    rule  @com_github_google_protobuf//:protobuf_java
-objc_library    rule  @com_github_google_protobuf//:protobuf_objc
-py_library      rule  @com_github_google_protobuf//:protobuf_python
-...
-

This is possible because the protobuf team provides a -BUILD file at -the root of their repository. Thanks Protobuf team! Later we’ll -learn how to “inject” our own BUILD files into repositories that don’t -already have one.

- -

Inspecting the list above, we see a cc_binary rule named protoc. -If we bazel run that target, bazel will clone the protobuf repo, -build all the dependent libraries, build a pristine executable binary -from source, and call it (pass command line arguments to binary rules -after the double-dash):

-
~/rules_protobuf$ bazel run @com_github_google_protobuf//:protoc -- --help
-Usage: /private/var/tmp/_bazel_pcj/63330772b4917b139280caef8bb81867/execroot/rules_protobuf/bazel-out/local-fastbuild/bin/external/com_github_google_protobuf/protoc [OPTION] PROTO_FILES
-Parse PROTO_FILES and generate output based on the options given:
-  -IPATH, --proto_path=PATH   Specify the directory in which to search for
-                              imports.  May be specified multiple times;
-                              directories will be searched in order.  If not
-                              given, the current working directory is used.
-  --version                   Show version info and exit.
-  -h, --help                  Show this text and exit.
-...
-

As we’ll see in a moment, we name the protobuf external dependency -with a specific commit ID so there’s no ambiguity about which protoc -version we’re using. In this way you can vendor in tools with your -project with reliable, repeable, secure precision without bloating -your repository by checking in binaries, resorting to git submodules, -or similar hacks. Very clean!

- -
-

Note: the gRPC repository also has a BUILD file: $ bazel query -@com_github_grpc_grpc//... --output label_kind

-
- -

1.3: Target Pattern Syntax

- -

With those examples under our belt, let’s examine the target syntax a -bit more. When I first started working with bazel I found the -target-pattern syntax somewhat intimidating. It’s actually not too -bad. Here’s a closer look:

- -

- - - -
-

A common source of confusion is that the mere presence of a -BUILD file defines that filesystem subtree as a package and -therefore one must always account for that. For example, if there -exists a file qux.js in foo/bar/baz/ and there exists a BUILD -file in baz/ also, the file is selected with foo/bar/baz:qux.js -and not foo/bar/baz/quz.js

-
- -

Common shortcut: if there exists a rule having the same name as the -package, this is the implied target and can be omitted. For example, -there is a :jar target in the //jar package in the external -workspace com_google_guava_guava, so the following are eqivalent:

-
deps = ["@com_google_guava_guava//jar:jar"]
-deps = ["@com_google_guava_guava//jar"]
-

1.4: External Dependencies: Workspace Rules

- -

Many large organizations check-in in all the required tools, -compilers, linkers, etc to guarantee correct, repeatable builds. With -external workspaces, one can effectively accomplish the same thing -without bloating your repository.

- -
-

Note: the bazel convention is to use a fully-namespaced identifier -for external dependency names (replacing special chars with -underscore). For example, the remote repository URL is -https://github.com/google/protobuf.git. This is simplified to the -workspace identifier com_github_google_protobuf. Similarly, by -convention the jar artifact io.grpc:grpc-netty:jar:1.0.0-pre1 -becomes io_grpc_grpc_netty.

-
- -

1.4.1: Workspace Rules that require a pre-existing WORKSPACE

- -

These rules assume that the remote resource or URL contains a -WORKSPACE file at the top of the file tree and BUILD files that define -rule targets. These are referred to as bazel repositories.

- - - -
-

Note: although you don’t interact directly with the bazel -execution_root, you can peek at what these external dependencies -look like when unpacked at $(bazel info -execution_root)/external/WORKSPACE_NAME.

-
- -

1.4.2: Workspace Rules that autogenerate a WORKSPACE file for you

- -

The implementation of these repository rules contain logic to -autogenerate a WORKSPACE file and BUILD file(s) to make resources -available. As always, it is recommended to provide a known sha265 for -security to prevent a malicious agent from slipping in tainted code -via a compromised network.

- - - -

For example, we can peek at the generated BUILD file for the -maven_jar guava dependency via:

-
~/rules_protobuf$ cat $(bazel info execution_root)/external/com_google_guava_guava/jar/BUILD
# DO NOT EDIT: automatically generated BUILD file for maven_jar rule com_google_guava_guava
-java_import(
-    name = 'jar',
-    jars = ['guava-19.0.jar'],
-    visibility = ['//visibility:public']
-)
-
-filegroup(
-    name = 'file',
-    srcs = ['guava-19.0.jar'],
-    visibility = ['//visibility:public']
-)
-
-

Note: the external workspace directory won’t exist until you -actually need it, so you’ll have to have built a target that -requires it, such as bazel build -examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/client

-
- -

1.4.3: Workspace Rules that accept a BUILD file as an argument

- -

If a repository has no BUILD file(s), you can put one into its -filesystem root to adapt the external resource into bazel’s worldview -and make those resources available to your project.

- -

For example, consider -Mark Adler’s zlib library. To start, -let’s learn what depends on this code. This query says “Ok bazel, -for all targets in examples, find all dependencies (a transitive -closure set), then tell me which ones depend on the zlib target in the -root package of the external workspace com_github_madler_zlib.” Bazel -reports this reverse dependency set. We request the output in -graphviz format and pipe this to dot to generate the figure:

-
~/rules_protobuf$ bazel query "rdeps(deps(//examples/...), @com_github_madler_zlib//:zlib)" \
-                  --output graph | dot -Tpng -O
-

- -

So we can see that all grpc-related C code ultimately depends on this -library. But, there is no BUILD file in Mark’s repo… where did it -come from?

- -

By using the variant workspace rule new_git_repository, we can -provide our -own BUILD file -(which defines the cc_library target) as follows:

-
new_git_repository(
-  name = "com_github_madler_zlib",
-  remote = "https://github.com/madler/zlib",
-  tag: "v1.2.8",
-  build_file: "//bzl:build_file/com_github_madler_zlib.BUILD",
-)
-

This new_* family of workspace rules keeps your repository lean and -allows you to vendor in pretty much any type of network-available -resource. Awesome!

- - - -
-

You can also -write your own repository rules -that have custom logic to pull resources from the net and bind it -into bazel’s view of the universe.

-
- -

1.5: Bazel Summary

- -

When presented with a command and a target-pattern, bazel goes through -the following three phases:

- -
    -
  1. Loading: Read the WORKSPACE and required BUILD files. Generate a -dependency graph.

  2. - -
  3. Analysis: for all nodes in the graph, which nodes are actually -required for this build? Do we have all the necessary -resources available?

  4. - -
  5. Execution: execute each required node in the dependency graph and -generate outputs.

  6. -
- -

Hopefully you now have enough conceptual knowledge of bazel to be -productive.

- -

1.6: rules_protobuf

- -

rules_protobuf is an -extension to bazel that takes care of:

- -
    -
  1. Building the protocol buffer compiler protoc,

  2. - -
  3. Downloading and/or building all the necessary protoc-gen plugins.

  4. - -
  5. Downloading and/or building all the necessary gRPC-related support -libraries.

  6. - -
  7. Invoking protoc for you (on demand), smoothing out the -idiosyncracies of different protoc plugins.

  8. -
- -

It works by passing one or more proto_language specifications to the -proto_compile rule. A proto_language rule contains the metadata -about how to invoke the plugin and the predicted file outputs, while -the proto_compile rule interprets a proto_language spec and builds -the appropriate command-line arguments to protoc. For example, -here’s how we can generate outputs for multiple languages -simultaneously:

-
 proto_compile(
-   name = "pluriproto",
-   protos = [":protos"],
-   langs = [
-       "//cpp",
-       "//csharp",
-       "//closure",
-       "//ruby",
-       "//java",
-       "//java:nano",
-       "//python",
-       "//objc",
-       "//node",
-   ],
-   verbose = 1,
-   with_grpc = True,
- )
$ bazel build :pluriproto
-# ************************************************************
-cd $(bazel info execution_root) && bazel-out/host/bin/external/com_github_google_protobuf/protoc \
---plugin=protoc-gen-grpc-java=bazel-out/host/genfiles/third_party/protoc_gen_grpc_java/protoc_gen_grpc_java \
---plugin=protoc-gen-grpc=bazel-out/host/bin/external/com_github_grpc_grpc/grpc_cpp_plugin \
---plugin=protoc-gen-grpc-nano=bazel-out/host/genfiles/third_party/protoc_gen_grpc_java/protoc_gen_grpc_java \
---plugin=protoc-gen-grpc-csharp=bazel-out/host/genfiles/external/nuget_grpc_tools/protoc-gen-grpc-csharp \
---plugin=protoc-gen-go=bazel-out/host/bin/external/com_github_golang_protobuf/protoc_gen_go \
---descriptor_set_out=bazel-genfiles/examples/proto/pluriproto.descriptor_set \
---ruby_out=bazel-genfiles \
---python_out=bazel-genfiles \
---cpp_out=bazel-genfiles \
---grpc_out=bazel-genfiles \
---objc_out=bazel-genfiles \
---csharp_out=bazel-genfiles/examples/proto \
---java_out=bazel-genfiles/examples/proto/pluriproto_java.jar \
---javanano_out=ignore_services=true:bazel-genfiles/examples/proto/pluriproto_nano.jar \
---js_out=import_style=closure,error_on_name_conflict,binary,library=examples/proto/pluriproto:bazel-genfiles \
---js_out=import_style=commonjs,error_on_name_conflict,binary:bazel-genfiles \
---go_out=plugins=grpc,Mexamples/proto/common.proto=github.com/pubref/rules_protobuf/examples/proto/pluriproto:bazel-genfiles \
---grpc-java_out=bazel-genfiles/examples/proto/pluriproto_java.jar \
---grpc-nano_out=ignore_services=true:bazel-genfiles/examples/proto/pluriproto_nano.jar \
---grpc-csharp_out=bazel-genfiles/examples/proto \
---proto_path=. \
-examples/proto/common.proto
-# ************************************************************
-examples/proto/common_pb.rb
-examples/proto/pluriproto_java.jar
-examples/proto/pluriproto_nano.jar
-examples/proto/common_pb2.py
-examples/proto/common.pb.h
-examples/proto/common.pb.cc
-examples/proto/common.grpc.pb.h
-examples/proto/common.grpc.pb.cc
-examples/proto/Common.pbobjc.h
-examples/proto/Common.pbobjc.m
-examples/proto/pluriproto.js
-examples/proto/Common.cs
-examples/proto/CommonGrpc.cs
-examples/proto/common.pb.go
-examples/proto/common_pb.js
-examples/proto/pluriproto.descriptor_set
-

The various *_proto_library rules (that we’ll be using below) -internally invoke this proto_compile rule, then consume the -generated outputs and compile them with the requisite libraries into -.class, .so, .a (or whatever) objects.

- -

So let’s make something already! We’ll use bazel and rules_protobuf -to build a gRPC application.

- -

2: Building a gRPC service with rules_protobuf

- -

The application will involve communication between two -different gRPC services:

- -

2.1: Services

- -
    -
  1. The Greeter service: This is the familiar “Hello World” starter -example that accepts a request with a user argument and replies -back with the string Hello {user}.

  2. - -
  3. The GreeterTimer service: This gRPC service will repeatedly -call a Greeter service in batches and report back aggregate batch -times (in milliseconds). In this way we can compare some average -rpc times for the different Greeter service implementations.

  4. -
- -
-

This is an informal benchmark intended only for demonstration of -building gRPC applications. For more formal performance testing, -consult the -gRPC performance dashboard.

-
- -

2.2: Compiled Programs

- -

For the demo, we’ll use 6 different compiled programs written in 4 -languages:

- - - -

2.3: Protobuf Definitions

- -

GreeterTimer accepts a unary TimerRequest and streams back a -sequence of BatchReponse until all messages have been processed, at -which point the remote procedure call is complete.

-
service GreeterTimer {
-  // Unary request followed by multiple streamed responses.
-  // Response granularity will be set by the request batch size.
-  rpc timeHello(TimerRequest) returns (stream BatchResponse);
-}
-

TimerRequest includes metadata about where to contact the Greeter -service, how many total RPC calls to make, and how frequent to stream -back a BatchResponse (configured via the batch size).

-
message TimerRequest {
-  // the host where the grpc server is running
-  string host = 1;
-  // The port of the grpc server
-  int32 port = 2;
-  // The total number of hellos
-  int32 total = 3;
-  // The number of hellos before sending a BatchResponse.
-  int32 batchSize = 4;
-}
-

BatchResponse reports the number of calls made in the batch, how -long the batch run took, and the number of remaining calls.

-
message BatchResponse {
-  // The number of checks that are remaining, calculated relative to
-  // totalChecks in the request.
-  int32 remaining = 1;
-  // The number of checks actually performed in this batch.
-  int32 batchCount = 2;
-  // The number of checks that failed.
-  int32 errCount = 3;
-  // The total time spent, expressed as a number of milliseconds per
-  // request batch size (total time spent performing batchSize number
-  // of health checks).
-  int64 batchTimeMillis = 4;
-}
-

The non-streaming Greeter service takes a unary HelloRequest and -responds with a single HelloReply:

-
service Greeter {
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-message HelloRequest {
-  string name = 1;
-  common.Config config = 2;
-}
-
-message HelloReply {
-  string message = 1;
-}
-
-

The common.Config message type is not particularly functional here -but serves to demonstrate the use of imports. rules_protobuf can -help with more complex setups having multiple proto → proto -dependencies.

-
- -

2.4: Build the grpc_greetertimer example application.

- -

This demo application can be cloned at -https://github.com/pubref/grpc_greetertimer.

- -

2.4.1: Create the Project Layout

- -

Here’s the directory layout and relevant BUILD files we’ll be using:

-
~$ mkdir grpc_greetertimer && cd grpc_greetertimer
-~/grpc_greetertimer$ mkdir -p proto/ go/ java/org/pubref/grpc/greetertimer/
-~/grpc_greetertimer$ touch WORKSPACE
-~/grpc_greetertimer$ touch proto/BUILD
-~/grpc_greetertimer$ touch proto/greetertimer.proto
-~/grpc_greetertimer$ touch go/BUILD
-~/grpc_greetertimer$ touch go/main.go
-~/grpc_greetertimer$ touch java/org/pubref/grpc/greetertimer/BUILD
-~/grpc_greetertimer$ touch java/org/pubref/grpc/greetertimer/GreeterTimerServer.java
-

2.4.2: The WORKSPACE

- -

We’ll begin by creating the WORKSPACE file with a -reference to the rules_protobuf repository. We load the main -entrypoint skylark file -rules.bzl -in the //bzl package and call its protobuf_repositories function -with the languages to we want to use (in this case java and go). -We also load rules_go for go -compile support (not shown).

-
# File //:WORKSPACE
-workspace(name = "org_pubref_grpc_greetertimer")
-
-git_repository(
-    name = "org_pubref_rules_protobuf",
-    remote = "https://github.com/pubref/rules_protobuf.git",
-    tag = "v0.6.0",
-)
-
-# Load language-specific dependencies
-load("@org_pubref_rules_protobuf//java:rules.bzl", "java_proto_repositories")
-java_proto_repositories()
-
-load("@org_pubref_rules_protobuf//go:rules.bzl", "go_proto_repositories")
-go_proto_repositories()
-
-

Refer to the -repositories.bzl file, -if you are interested in inspecting the dependencies.

-
- -

Bazel won’t actually fetch something unless we actually need it by -some other rule later, so let’s go ahead and write some code. We’ll -store our protocol buffer sources in //proto, our java sources in -//java, and go source in //go.

- -
-

Note: go development within a bazel workspace is a little different -than vanilla go. In particular, one does not have to adhere to a -typical GOCODE layout having a src/, pkg/, bin/ -subdirectories.

-
- -

2.4.3: The GreeterTimer Server

- -

The -java server’s -main job is to accept requests and then connect to the requested -Greeter service as a client. The implementation counts down the -number of remaining messages and does a blocking sayHello(request) -for each one. If the batchSize limit is met, the -observer.onNext(response) message is invoked, streaming back a -response to the client.

-
/* File //java/org/pubref/grpc/greetertimer:GreeterTimerServer.java */
-
-  while (remaining-- > 0) {
-
-    if (batchCount++ == batchSize) {
-      BatchResponse response = BatchResponse.newBuilder()
-        .setRemaining(remaining)
-        .setBatchCount(batchCount)
-        .setBatchTimeMillis(batchTime)
-        .setErrCount(errCount)
-        .build();
-      observer.onNext(response);
-    }
-
-    blockingStub.sayHello(HelloRequest.newBuilder()
-                          .setName("#" + remaining)
-                          .build());
-  }
-}
-

2.4.4: The GreeterTimer Client

- -

The -go client -prepares a TimerRequest and gets back a stream interface from the -client.TimeHello method. We call its Recv() method until EOF, at -which point the call is complete. A summary of each BatchResponse is -simply printed out to the terminal.

-
// File: //go:main.go
-
-func submit(client greeterTimer.GreeterTimerClient, request *greeterTimer.TimerRequest) error {
-	stream, err := client.TimeHello(context.Background(), request)
-	if err != nil {
-		log.Fatalf("could not submit request: %v", err)
-	}
-	for {
-		batchResponse, err := stream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			log.Fatalf("error during batch recv: %v", err)
-			return err
-		}
-		reportBatchResult(batchResponse)
-	}
-}
-

2.4.5: Generate the go protobuf+gRPC code

- -

In our //proto:BUILD file, we have a go_proto_library rule loaded -from the rules_protobuf repository. Internally, the rule declares to -bazel that it is responsible for creating greetertimer.pb.go output -file. This rule won’t actually do anything unless we depend on it -somewhere else.

-
# File: //proto:BUILD
-load("@org_pubref_rules_protobuf//go:rules.bzl", "go_proto_library")
-
-go_proto_library(
-    name = "go_default_library",
-    protos = [
-        "greetertimer.proto",
-    ],
-    with_grpc = True,
-)
-

The go client implementation depends on the go_proto_library as -source file provider to the go_binary rule. We also pass in some -compile-time dependencies named in the -GRPC_COMPILE_DEPS list.

-
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
-load("@org_pubref_rules_protobuf//go:rules.bzl", "GRPC_COMPILE_DEPS")
-
-go_binary(
-    name = "hello_client",
-    srcs = [
-        "main.go",
-    ],
-    deps = [
-        "//proto:go_default_library",
-    ] + GRPC_COMPILE_DEPS,
-)
~/grpc_greetertimer$ bazel build //go:client
-

Here’s what happens when we invoke bazel to actually build the client -binary:

- -
    -
  1. Bazel checks to see if the inputs (files) that the binary depends -on have changed (by content hash and filestamps). Bazel recognizes -that the output files for the //proto:go_default_library have not -been built.

  2. - -
  3. Bazel checks to see if all the necessary inputs (including tools) -for the go_proto_library are available. If not, download and -build all the necessary tools. Then, invoke the rule.

    - -
      -
    1. Fetch the google/protobuf repository and build protoc from -source (via a cc_binary rule).

    2. - -
    3. Build the protoc-gen-go plugin from source (via a go_binary -rule).

    4. - -
    5. Invoke protoc with the protoc-gen-go plugin with the -appropriate options and arguments.

    6. - -
    7. Confirm that all the declared outputs of the go_proto_library -where actually built (should be in bazel-bin/proto/greetertimer.pb.go).

    8. -
  4. - -
  5. Compile the generated greetertimer.pb.go with the client -main.go file, creating the bazel-bin/go/client executable.

  6. -
- -

2.4.6: Generate the java protobuf libraries

- -

The java_proto_library rule is functionally identical to the -go_proto_library rule. However, instead of providing a *.pb.go -file, it bundles up all the generated outputs into a *.srcjar file -(which is then used as an input to the java_library rule). This an -implementation detail of the java rule. Here is how we build the -final java binary:

-
java_binary(
-    name = "server",
-    main_class = "org.pubref.grpc.greetertimer.GreeterTimerServer",
-    srcs = [
-        "GreeterTimerServer.java",
-    ],
-    deps = [
-        ":timer_protos",
-        "@org_pubref_rules_protobuf//examples/helloworld/proto:java",
-        "@org_pubref_rules_protobuf//java:grpc_compiletime_deps",
-    ],
-    runtime_deps = [
-        "@org_pubref_rules_protobuf//java:netty_runtime_deps",
-    ],
-)
-
    -
  1. The :timer_protos is a locally defined java_proto_library rule.

  2. - -
  3. The @org_pubref_rules_protobuf//examples/helloworld/proto:java is -an external java_proto_library rule that generates the greeter service -client stub in our own workspace.

  4. - -
  5. Finally, we name the compile-time and run-time dependencies for the -executable jar. If these jar files have not yet been downloaded from -maven central, they will be fetch as soon as we need them:

  6. -
-
~/grpc_greetertimer$ bazel build java/org/pubref/grpc/greetertimer:server
-~/grpc_greetertimer$ bazel build java/org/pubref/grpc/greetertimer:server_deploy.jar
-

This last form (having the extra _deploy.jar) is called an implicit -target of the :server rule. When invoked this way, bazel will pack -up all the required classes and generate a standalone executable jar -that can be run independently in a jvm.

- -

2.4.7: Run it!

- -

First, we’ll start a greeter server (one at a time):

-
~/grpc_greetertimer$ cd ~/rules_protobuf
-~/rules_protobuf$ bazel run examples/helloworld/go/server
-~/rules_protobuf$ bazel run examples/helloworld/cpp/server
-~/rules_protobuf$ bazel run examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/server:netty
-~/rules_protobuf$ bazel run examples/helloworld/csharp/GreeterServer
-INFO: Server started, listening on 50051
-

In a separate terminal, start the greetertimer server:

-
~/grpc_greetertimer$ bazel build //java/org/pubref/grpc/greetertimer:server_deploy.jar
-~/grpc_greetertimer$ java -jar bazel-bin/java/org/pubref/grpc/greetertimer/server_deploy.jar
-

Finally, in a third terminal, invoke the greetertimer client:

-
# Timings for the java server
-~/rules_protobuf$ bazel run examples/helloworld/java/org/pubref/rules_protobuf/examples/helloworld/server:netty
-
-~/grpc_greeterclient$ bazel run //go:client -- -total_size 10000 -batch_size 1000
-17:31:04 1001 hellos (0 errs, 8999 remaining): 1.7 hellos/ms or ~590µs per hello
-# ... plus a few runs to warm up the jvm...
-17:31:13 1001 hellos (0 errs, 8999 remaining): 6.7 hellos/ms or ~149µs per hello
-17:31:13 1001 hellos (0 errs, 7998 remaining): 9.0 hellos/ms or ~111µs per hello
-17:31:13 1001 hellos (0 errs, 6997 remaining): 8.9 hellos/ms or ~112µs per hello
-17:31:13 1001 hellos (0 errs, 5996 remaining): 9.2 hellos/ms or ~109µs per hello
-17:31:13 1001 hellos (0 errs, 4995 remaining): 9.4 hellos/ms or ~106µs per hello
-17:31:13 1001 hellos (0 errs, 3994 remaining): 9.0 hellos/ms or ~111µs per hello
-17:31:13 1001 hellos (0 errs, 2993 remaining): 9.4 hellos/ms or ~107µs per hello
-17:31:13 1001 hellos (0 errs, 1992 remaining): 9.4 hellos/ms or ~107µs per hello
-17:31:13 1001 hellos (0 errs, 991 remaining): 9.1 hellos/ms or ~110µs per hello
-17:31:14 991 hellos (0 errs, -1 remaining): 9.0 hellos/ms or ~111µs per hello```
-
-```sh
-# Timings for the go server
-~/rules_protobuf$ bazel run examples/helloworld/go/server
-
-~/grpc_greeterclient$ bazel run //go:client -- -total_size 10000 -batch_size 1000
-17:32:33 1001 hellos (0 errs, 8999 remaining): 7.5 hellos/ms or ~134µs per hello
-17:32:33 1001 hellos (0 errs, 7998 remaining): 7.9 hellos/ms or ~127µs per hello
-17:32:34 1001 hellos (0 errs, 6997 remaining): 7.8 hellos/ms or ~128µs per hello
-17:32:34 1001 hellos (0 errs, 5996 remaining): 7.7 hellos/ms or ~130µs per hello
-17:32:34 1001 hellos (0 errs, 4995 remaining): 7.9 hellos/ms or ~126µs per hello
-17:32:34 1001 hellos (0 errs, 3994 remaining): 8.0 hellos/ms or ~125µs per hello
-17:32:34 1001 hellos (0 errs, 2993 remaining): 7.6 hellos/ms or ~132µs per hello
-17:32:34 1001 hellos (0 errs, 1992 remaining): 7.9 hellos/ms or ~126µs per hello
-17:32:34 1001 hellos (0 errs, 991 remaining): 7.9 hellos/ms or ~127µs per hello
-17:32:34 991 hellos (0 errs, -1 remaining): 7.8 hellos/ms or ~128µs per hello
# Timings for the C++ server
-~/rules_protobuf$ bazel run examples/helloworld/cpp:server
-
-~/grpc_greeterclient$ bazel run //go:client -- -total_size 10000 -batch_size 1000
-17:33:10 1001 hellos (0 errs, 8999 remaining): 9.1 hellos/ms or ~110µs per hello
-17:33:10 1001 hellos (0 errs, 7998 remaining): 9.0 hellos/ms or ~111µs per hello
-17:33:10 1001 hellos (0 errs, 6997 remaining): 9.1 hellos/ms or ~110µs per hello
-17:33:10 1001 hellos (0 errs, 5996 remaining): 8.6 hellos/ms or ~116µs per hello
-17:33:10 1001 hellos (0 errs, 4995 remaining): 9.0 hellos/ms or ~111µs per hello
-17:33:10 1001 hellos (0 errs, 3994 remaining): 9.0 hellos/ms or ~111µs per hello
-17:33:10 1001 hellos (0 errs, 2993 remaining): 9.1 hellos/ms or ~110µs per hello
-17:33:10 1001 hellos (0 errs, 1992 remaining): 9.0 hellos/ms or ~111µs per hello
-17:33:10 1001 hellos (0 errs, 991 remaining): 9.0 hellos/ms or ~111µs per hello
-17:33:11 991 hellos (0 errs, -1 remaining): 9.0 hellos/ms or ~111µs per hello
# Timings for the C# server
-~/rules_protobuf$ bazel run examples/helloworld/csharp/GreeterServer
-
-~/grpc_greeterclient$ bazel run //go:client -- -total_size 10000 -batch_size 1000
-17:34:37 1001 hellos (0 errs, 8999 remaining): 6.0 hellos/ms or ~166µs per hello
-17:34:37 1001 hellos (0 errs, 7998 remaining): 6.7 hellos/ms or ~150µs per hello
-17:34:37 1001 hellos (0 errs, 6997 remaining): 6.8 hellos/ms or ~148µs per hello
-17:34:37 1001 hellos (0 errs, 5996 remaining): 6.8 hellos/ms or ~147µs per hello
-17:34:37 1001 hellos (0 errs, 4995 remaining): 6.7 hellos/ms or ~150µs per hello
-17:34:38 1001 hellos (0 errs, 3994 remaining): 6.7 hellos/ms or ~150µs per hello
-17:34:38 1001 hellos (0 errs, 2993 remaining): 6.7 hellos/ms or ~149µs per hello
-17:34:38 1001 hellos (0 errs, 1992 remaining): 6.7 hellos/ms or ~149µs per hello
-17:34:38 1001 hellos (0 errs, 991 remaining): 6.8 hellos/ms or ~148µs per hello
-17:34:38 991 hellos (0 errs, -1 remaining): 6.8 hellos/ms or ~147µs per hello
-

The informal analysis demonstrated comparable timings for c++, go, and -java greeter service implementations. The c++ server had the overall -fastest and most consistent performance. The go implementation was -also very consistent, but slightly slower than C++. Java demonstrated -some initial relative slowness likely due to the JVM warming up but -soon converged on timings similar to the C++ implementation. C# has -consistent performance but marginally slower.

- -

2.5: Summary

- -

Bazel assists in the construction of gRPC applications by providing a -capable build environment for services built in a multitude of -languages. rules_protobuf complements bazel by packaging up all the -dependencies needed and abstracting away the need to call protoc -directly.

- -

In this workflow one does not need to check in the generated source code -(it is always generated on-demand within your workspace). For -projects that do require this, one can use the output_to_workspace option to place the generated -files alongside the protobuf definitions.

- -

Finally, rules_protobuf has full support for the -grpc-gateway project -via the -grpc_gateway_proto_library -and -grpc_gateway_binary rules, so you can easily bridge your gRPC apps with HTTP/1.1 gateways.

- -

Refer to the complete list of supported languages and gRPC versions for more information.

- -

And… that’s a wrap. Happy procedure calling!

- -
-

Paul Johnston is the principal at PubRef -(@pub_ref), a solutions provider for -scientific communications workflows. If you have an organizational -need for assistance with Bazel, gRPC, or related technologies, -please contact pcj@pubref.org. Thanks!

-
-

- - -
- - - - - - - - - - diff --git a/public/blog/beta_release/index.html b/public/blog/beta_release/index.html deleted file mode 100644 index 2658c77..0000000 --- a/public/blog/beta_release/index.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - gRPC releases Beta, opening door for use in production environments. – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC releases Beta, opening door for use in production environments.

-
Posted on Monday, October 26, 2015 - - - - -
-

-

- We’re also taking a big step forward in improving the installation process. Over the past few weeks we’ve rolled out gRPC packages to Debian Stable/Backports. Installation in most cases is now a two line install using the Debian package and available language specific package managers (maven, pip, gem, composer, pecl, npm, nuget, pod). In addition gRPC docker images are now available on Docker Hub. -

-

- We’ve updated the documentation on grpc.io to reflect the latest changes and released additional language-specific reference docs. See what’s changed with the Beta release in the release notes on GitHub for Java, Go and all other languages. -

-

- In keeping in line with our principles and goal to enable highly performant and scalable APIs and microservices on top of HTTP/2, in the coming months, the focus of the gRPC project will be to keep improving performance and stability and adding carefully chosen features for production use cases. Documentation will also be clarified and will continue to improve with new examples and guides. -

-

- We’ve been very excited to see the community response to gRPC and the various projects starting to use it (etcd v3 experimental api, grpc-gateway for RESTful APIs and others). -

-

- We really want to thank everyone who contributed code, gave presentations, adopted the technology and engaged in the community. With your help support we look forward to the 1.0! -

- -

- - -
- - - - - - - - - - diff --git a/public/blog/coreos/index.html b/public/blog/coreos/index.html deleted file mode 100644 index 29b48af..0000000 --- a/public/blog/coreos/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - gRPC with REST and Open APIs – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC with REST and Open APIs

-
Posted on Monday, May 09, 2016 - by - - Brandon Phillips - -
-

-

Our guest post today comes from Brandon Phillips of CoreOS. CoreOS builds open source projects and products for Linux Containers. Their flagship product for consensus and discovery etcd and their container engine rkt are early adopters of gRPC.

- -

One of the key reasons CoreOS chose gRPC is because it uses HTTP/2, enabling applications to present both a HTTP 1.1 REST/JSON API and an efficient gRPC interface on a single TCP port (available for Go). This provides developers with compatibility with the REST web ecosystem, while advancing a new, high-efficiency RPC protocol. With the recent release of Go 1.6, Go ships with a stable net/http2 package by default.

- -

Since many CoreOS clients speak HTTP 1.1 with JSON, gRPC’s easy interoperability with JSON and the Open API Specification (formerly Swagger) was extremely valuable. For their users who are more comfortable with HTTP/1.1+JSON-based and Open API Spec APIs they used a combination of open source libraries to make their gRPC services available in both gRPC and HTTP REST flavors, using API multiplexers to give users the best of both worlds. Let’s dive into the details and find out how they did it!

- -

This post was originally published at the CoreOS blog. We are reproducing it here with some edits.

- -

A gRPC application called EchoService

- -

In this post we will build a small proof-of-concept gRPC application from a gRPC API definition, add a REST service gateway, and finally serve it all on a single TLS port. The application is called EchoService, and is the web equivalent of the shell command echo: the service returns, or “echoes”, whatever text is sent to it.

- -

First, let’s define the arguments to EchoService in a protobuf message called EchoMessage, which includes a single field called value. We will define this message in a protobuf “.proto” file called service.proto. Here is our EchoMessage:

-
message EchoMessage {
- string value = 1;
-}
-

In this same .proto file, we define a gRPC service that takes this data structure and returns it:

-
service EchoService {
-  rpc Echo(EchoMessage) returns (EchoMessage) {
-  }
-}
-

Running this service.proto file “as is” through the Protocol Buffer compiler protoc generates a stub gRPC service in Go, along with clients in various languages. But gRPC alone isn’t as useful as a service that also exposes a REST interface, so we won’t stop with the gRPC service stub.

- -

Next, we add the gRPC REST Gateway. This library will build a RESTful proxy on top of the gRPC EchoService. To build this gateway, we add metadata to the EchoService .proto to indicate that the Echo RPC maps to a RESTful POST method with all RPC parameters mapped to a JSON body. The gateway can map RPC parameters to URL paths and query parameters, but we omit those complications here for brevity.

-
service EchoService {
-  rpc Echo(EchoMessage) returns (EchoMessage) {
-    option (google.api.http) = {
-      post: "/v1/echo"
-      body: "*"
-    };
-  }
-}
-

This means the gateway, once generated by protoc, can now accept a HTTP request from curl like this:

-
curl -X POST -k https://localhost:10000/v1/echo -d '{"value": "CoreOS is hiring!"}'
-

The whole system so far looks like this, with a single service.proto file generating both a gRPC server and a REST proxy:

- -

gRPC API with REST gateway

- -

To bring this all together, the echo service creates a Go http.Handler to detect if the protocol is HTTP/2 and the Content-Type is “application/grpc”, and sends such requests to the gRPC server. Everything else is routed to the REST gateway. The code looks something like this:

-
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
-	grpcServer.ServeHTTP(w, r)
-} else {
-	otherHandler.ServeHTTP(w, r)
-}
-

To try it out, all you need is a working Go 1.6 development environment and the following simple commands:

-
$ go get -u github.com/philips/grpc-gateway-example
-$ grpc-gateway-example serve
-

With the server running you can try requests on both HTTP 1.1 and gRPC interfaces:

-
grpc-gateway-example echo Take a REST from REST with gRPC
-curl -X POST -k https://localhost:10000/v1/echo -d '{"value": "CoreOS is hiring!"}'
-

One last bonus: because we have an Open API specification, you can browse the Open API UI running at https://localhost:10000/swagger-ui/#!/EchoService/Echo if you have the server above running on your laptop.

- -

gRPC/REST Open API document

- -

We’ve taken a look at how to use gRPC to bridge to the world of REST. If you want to take a look at the complete project, check out the repo on GitHub. We think this pattern of using a single protobuf to describe an API leads to an easy to consume, flexible API framework, and we’re excited to leverage it in more of our projects.

-

- - -
- - - - - - - - - - diff --git a/public/blog/deadlines/index.html b/public/blog/deadlines/index.html deleted file mode 100644 index 9b6ddf1..0000000 --- a/public/blog/deadlines/index.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - - - gRPC and Deadlines – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC and Deadlines

-
Posted on Monday, February 26, 2018 - by - - Gráinne Sheerin, Google SRE - -
-

-

TL;DR Always set a deadline. This post explains why we recommend being deliberate about setting deadlines, with useful code snippets to show you how.

- -

When you use gRPC, the gRPC library takes care of communication, marshalling, unmarshalling, and deadline enforcement. Deadlines allow gRPC clients to specify how long they are willing to wait for an RPC to complete before the RPC is terminated with the error DEADLINE_EXCEEDED. By default this deadline is a very large number, dependent on the language implementation. How deadlines are specified is also language-dependent. Some language APIs work in terms of a deadline, a fixed point in time by which the RPC should complete. Others use a timeout, a duration of time after which the RPC times out.

- -

In general, when you don’t set a deadline, resources will be held for all in-flight requests, and all requests can potentially reach the maximum timeout. This puts the service at risk of running out of resources, like memory, which would increase the latency of the service, or could crash the entire process in the worst case.

- -

To avoid this, services should specify the longest default deadline they technically support, and clients should wait until the response is no longer useful to them. For the service this can be as simple as providing a comment in the .proto file. For the client this involves setting useful deadlines.

- -

There is no single answer to “What is a good deadline/timeout value?”. Your service might be as simple as the Greeter in our quick start guides, in which case 100 ms would be fine. Your service might be as complex as a globally-distributed and strongly consistent database. The deadline for a client query will be different from how long they should wait for you to drop their table.

- -

So what do you need to consider to make an informed choice of deadline? Factors to take into account include the end to end latency of the whole system, which RPCs are serial, and which can be made in parallel. You should to be able to put numbers on it, even if it’s a rough calculation. Engineers need to understand the service and then set a deliberate deadline for the RPCs between clients and servers.

- -

In gRPC, both the client and server make their own independent and local determination about whether the remote procedure call (RPC) was successful. This means their conclusions may not match! An RPC that finished successfully on the server side can fail on the client side. For example, the server can send the response, but the reply can arrive at the client after their deadline has expired. The client will already have terminated with the status error DEADLINE_EXCEEDED. This should be checked for and managed at the application level.

- -

Setting a deadline

- -

As a client you should always set a deadline for how long you are willing to wait for a reply from the server. Here’s an example using the greeting service from our Quick Start Guides:

- -

C++

-
ClientContext context;
-time_point deadline = std::chrono::system_clock::now() + 
-    std::chrono::milliseconds(100);
-context.set_deadline(deadline);
-
-

Go

-
clientDeadline := time.Now().Add(time.Duration(*deadlineMs) * time.Millisecond)
-ctx, cancel := context.WithDeadline(ctx, clientDeadline)
-

Java

-
response = blockingStub.withDeadlineAfter(deadlineMs, TimeUnit.MILLISECONDS).sayHello(request);
-

This sets the deadline to 100ms from when the client RPC is set to when the response is picked up by the client.

- -

Checking deadlines

- -

On the server side, the server can query to see if a particular RPC is no longer wanted. Before a server starts work on a response it is very important to check if there is still a client waiting for it. This is especially important to do before starting expensive processing.

- -

C++

-
if (context->IsCancelled()) {
-  return Status(StatusCode::CANCELLED, "Deadline exceeded or Client cancelled, abandoning.");
-}
-
-

Go

-
if ctx.Err() == context.Canceled {
-	return status.New(codes.Canceled, "Client cancelled, abandoning.")
-}
-

Java

-
if (Context.current().isCancelled()) {
-  responseObserver.onError(Status.CANCELLED.withDescription("Cancelled by client").asRuntimeException());
-  return;
-}
-

Is it useful for a server to continue with the request, when you know your client has reached their deadline? It depends. If the response can be cached in the server, it can be worth processing and caching it; particularly if it’s resource heavy, and costs you money for each request. This will make future requests faster as the result will already be available.

- -

Adjusting deadlines

- -

What if you set a deadline but a new release or server version causes a bad regression? The deadline could be too small, resulting in all your requests timing out with DEADLINE_EXCEEDED, or too large and your user tail latency is now massive. You can use a flag to set and adjust the deadline.

- -

C++

-
#include <gflags/gflags.h>
-DEFINE_int32(deadline_ms, 20*1000, "Deadline in milliseconds.");
-
-ClientContext context;
-time_point deadline = std::chrono::system_clock::now() + 
-    std::chrono::milliseconds(FLAGS_deadline_ms);
-context.set_deadline(deadline);
-
-

Go

-
var deadlineMs = flag.Int("deadline_ms", 20*1000, "Default deadline in milliseconds.")
-
-ctx, cancel := context.WithTimeout(ctx, time.Duration(*deadlineMs) * time.Millisecond)
-

Java

-
@Option(name="--deadline_ms", usage="Deadline in milliseconds.")
-private int deadlineMs = 20*1000;
-
-response = blockingStub.withDeadlineAfter(deadlineMs, TimeUnit.MILLISECONDS).sayHello(request);
-

Now the deadline can be adjusted to wait longer to avoid failing, without the need to cherry-pick a release with a different hard coded deadline. This lets you mitigate the issue for users until the regression can be debugged and resolved.

-

- - -
- - - - - - - - - - diff --git a/public/blog/flatbuffers/index.html b/public/blog/flatbuffers/index.html deleted file mode 100644 index d28c3d0..0000000 --- a/public/blog/flatbuffers/index.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - Announcing out of the box support for gRPC in the Flatbuffers serialization library. – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Announcing out of the box support for gRPC in the Flatbuffers serialization library.

-
Posted on Thursday, August 17, 2017 - by - - Wouter van Oortmerssen - -
-

-

The recent release of Flatbuffers version 1.7 introduced truly zero-copy support for gRPC out of the box.

- -

Flatbuffers is a serialization library that allows you to access serialized data without first unpacking it or allocating any -additional data structures. It was originally designed for games and other resource constrained applications, but is now finding more general use, both by teams within Google and in other companies such as Netflix and Facebook.

- -

Flatbuffers enables maximum throughput by directly using gRPC’s slice buffers with zero-copy for common use cases. An incoming rpc can be processed directly from gRPCs internal buffers, and constructing a new message will write directly to these buffers without intermediate steps.

- -

This is currently, fully supported in the C++ implementation of FlatBuffers, with more languages to come. There is also an implementation in Go, which is not entirely zero copy, but still very low on allocation cost (see below).

- -

Example Usage

- -

Let’s look at an example of how this works.

- -

Use Flatbuffers as an IDL

- -

Start with an .fbs schema (similar to .proto, if you are familiar with protocol buffers) that declares an RPC service:

-
table HelloReply {
-  message:string;
-}
-
-table HelloRequest {
-  name:string;
-}
-
-table ManyHellosRequest {
-  name:string;
-  num_greetings:int;
-}
-
-rpc_service Greeter {
-  SayHello(HelloRequest):HelloReply;
-  SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
-}
-

To generate C++ code from this, run: flatc --cpp --grpc example.fbs, much like in protocol buffers.

- -

Generated Server Implementation

- -

The server implementation is very similar to protocol buffers, except now the request and response messages are of type flatbuffers::grpc::Message<HelloRequest> *. -Unlike protocol buffers, where these types represent a tree of C++ objects, here they are merely handles to a flat object in the underlying gRPC slice. You can access the data directly:

-
auto request = request_msg->GetRoot();
-auto name = request->name()->str();
-
-

Building a response is equally simple

-
auto msg_offset = mb_.CreateString("Hello, " + name);
-auto hello_offset = CreateHelloReply(mb_, msg_offset);
-mb_.Finish(hello_offset);
-*response_msg = mb_.ReleaseMessage<HelloReply>();
-
-

The client code is the same as that generated by protocol buffers, except for the FlatBuffer access and construction code.

- -

See the full example here. To compile it, you need gRPC. -The same repo has a similar example for Go.

- -

Read more about using and building FlatBuffers for your platform on the flatbuffers site.

-

- - -
- - - - - - - - - - diff --git a/public/blog/gablogpost/index.html b/public/blog/gablogpost/index.html deleted file mode 100644 index ad353b2..0000000 --- a/public/blog/gablogpost/index.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - gRPC Project is now 1.0 and ready for production deployments – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC Project is now 1.0 and ready for production deployments

-
Posted on Tuesday, August 23, 2016 - by - - Varun Talwar - -
-

-

Today, the gRPC project has reached a significant milestone with its 1.0 release. -Languages moving to 1.0 include C++, Java, Go, Node, Ruby, Python and C# across Linux, Windows, and Mac. Objective-C and Android Java support on iOS and Android is also moving to 1.0. The 1.0 release means that the core protocol and API surface are now stable with measured performance, stress tested and developers can rely on these APIs and deploy in production, they will follow semantic versioning from here.

- -

We are very excited about the progress we have made so far and would like to thank all our users and contributors. First announced in March 2015 with Square, gRPC is already being used in many open source projects like etcd from CoreOS, containerd from Docker, cockroachdb from Cockroach Labs, and by many other companies like Vendasta, Netflix, YikYak and Carbon 3d. Outside of microservices, telecom giants like Cisco, Juniper, Arista, and Ciena, are building support for streaming telemetry and network configuration from their network devices using gRPC, as part of OpenConfig effort.

- -

From the beta release, we have made significant strides in the areas of usability, interoperability, and performance measurement on the road to 1.0. In most of the languages, the installation of the gRPC runtime as well as setup of a development environment is a single command. Beyond installation, we have set up automated tests for gRPC across languages and RPC types in order to stress test our APIs and ensure interoperability. There is now a performance dashboard available in the open to see latency and throughput for unary and streaming ping pong for various languages. Other measurements have shown significant gains from using gRPC/Protobuf instead of HTTP/JSON such as in CoreOS blogpost and in Google Cloud PubSub testing. In the coming months, we will invest a lot more in performance tuning.

- -

Even within Google, we have seen Google cloud APIs like BigTable, PubSub, Speech, launch of a gRPC-based API surface leading to ease of use and performance benefits. Products like Tensorflow have effectively used gRPC for inter-process communication as well. -Beyond usage, we are keen to see the contributor community grow with gRPC. We are already starting to see contributions around gRPC in meaningful ways in the grpc-ecosystem organization. We are very happy to see projects like grpc-gateway to enable users to serve REST clients with gRPC based services, Polyglot to have a CLI for gRPC, Prometheus monitoring of gRPC Services and work with OpenTracing. You can suggest and contribute projects to this organization here. We look forward to working with the community to take the gRPC project to new heights.

- -

- - -
- - - - - - - - - - diff --git a/public/blog/gracefully_clean_up_in_grpc_junit_tests/index.html b/public/blog/gracefully_clean_up_in_grpc_junit_tests/index.html deleted file mode 100644 index 1113864..0000000 --- a/public/blog/gracefully_clean_up_in_grpc_junit_tests/index.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - - - - Gracefully clean up in gRPC JUnit tests – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Gracefully clean up in gRPC JUnit tests

-
Posted on Tuesday, June 26, 2018 - by - - Dapeng Zhang - -
-

-

It is best practice to always clean up gRPC resources such as client channels, servers, and previously attached Contexts whenever they are no longer needed.

- -

This is even true for JUnit tests, because otherwise leaked resources may not only linger in your machine forever, but also interfere with subsequent tests. A not-so-bad case is that subsequent tests can’t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn’t have passed at all if the previously passed test had not leaked a resource.

- -

So cleanup, cleanup, cleanup… and fail the test if any cleanup is not successful.

- -

A typical example is

-
public class MyTest {
-  private Server server;
-  private ManagedChannel channel;
-  ...
-  @After
-  public void tearDown() throws InterruptedException {
-    // assume channel and server are not null
-    channel.shutdownNow();
-    server.shutdownNow();
-    // fail the test if cleanup is not successful
-    assert channel.awaitTermination(5, TimeUnit.SECONDS) : "channel failed to shutdown";
-    assert server.awaitTermination(5, TimeUnit.SECONDS) : "server failed to shutdown";
-  }
-  ...
-}
-

or to be more graceful

-
public class MyTest {
-  private Server server;
-  private ManagedChannel channel;
-  ...
-  @After
-  public void tearDown() throws InterruptedException {
-    // assume channel and server are not null
-    channel.shutdown();
-    server.shutdown();
-    // fail the test if cannot gracefully shutdown
-    try {
-      assert channel.awaitTermination(5, TimeUnit.SECONDS) : "channel cannot be gracefully shutdown";
-      assert server.awaitTermination(5, TimeUnit.SECONDS) : "server cannot be gracefully shutdown";
-    } finally {
-      channel.shutdownNow();
-      server.shutdownNow();
-    }
-  }
-  ...
-}
-

However, having to add all this to every test so it shuts down gracefully gives you more work to do, as you need to write the shutdown boilerplate by yourself. Because of this, the gRPC testing library has helper rules to make this job less tedious.

- -

Initially, a JUnit rule GrpcServerRule was introduced to eliminate the shutdown boilerplate. This rule creates an In-Process server and channel at the beginning of the test, and shuts them down at the end of test automatically. However, users found this rule too restrictive in that it does not support transports other than In-Process transports, multiple channels to the server, custom channel or server builder options, and configuration inside individual test methods.

- -

A more flexible JUnit rule GrpcCleanupRule was introduced in gRPC release v1.13, which also eliminates the shutdown boilerplate. However unlike GrpcServerRule, GrpcCleanupRule does not create any server or channel automatically at all. Users create and start the server by themselves, and create channels by themselves, just as in plain tests. With this rule, users just need to register every resource (channel or server) that needs to be shut down at the end of test, and the rule will then shut them down gracefully automatically.

- -

You can register resources either before running test methods

-
public class MyTest {
-  @Rule
-  public GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
-  ...
-  private String serverName = InProcessServerBuilder.generateName();
-  private Server server = grpcCleanup.register(InProcessServerBuilder
-      .forName(serverName).directExecutor().addService(myServiceImpl).build().start());
-  private ManagedChannel channel = grpcCleanup.register(InProcessChannelBuilder
-      .forName(serverName).directExecutor().build());
-  ...
-}
-

or inside each individual test method

-
public class MyTest {
-  @Rule
-  public GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
-  ...
-  private String serverName = InProcessServerBuilder.generateName();
-  private InProcessServerBuilder serverBuilder = InProcessServerBuilder
-      .forName(serverName).directExecutor();
-  private InProcessChannelBuilder channelBuilder = InProcessChannelBuilder
-      .forName(serverName).directExecutor();
-  ...
-
-  @Test
-  public void testFooBar() {
-    ...
-    grpcCleanup.register(
-    	serverBuilder.addService(myServiceImpl).build().start());
-    ManagedChannel channel = grpcCleanup.register(
-    	channelBuilder.maxInboundMessageSize(1024).build());
-    ...
-  }
-}
-

Now with GrpcCleanupRule you don’t need to worry about graceful shutdown of gRPC servers and channels in JUnit test. So try it out and clean up in your tests!

-

- - -
- - - - - - - - - - diff --git a/public/blog/grpc-dotnet-build/index.html b/public/blog/grpc-dotnet-build/index.html deleted file mode 100644 index 781eea2..0000000 --- a/public/blog/grpc-dotnet-build/index.html +++ /dev/null @@ -1,317 +0,0 @@ - - - - - - - - - - - - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

-
Posted on Tuesday, December 18, 2018 - by - - Kirill 'kkm' Katsnelson - -
-

-

As part of Microsoft’s move towards its cross-platform .NET offering, they have -greatly simplified the project file format, and allowed a tight integration of -third-party code generators with .NET projects. We are listening, and now proud -to introduce integrated compilation of Protocol Buffer and gRPC service -.proto files in .NET C# projects starting with the version 1.17 of the -Grpc.Tools NuGet package, now available from Nuget.org.

- -

You no longer need to use hand-written scripts to generate code from .proto -files: The .NET build magic handles this for you. The integrated tools locate -the proto compiler and gRPC plugin, standard Protocol Buffer imports, and track -dependencies before invoking the code generators, so that the generated C# -source files are never out of date, at the same time keeping regeneration to -the minimum required. In essence, .proto files are treated as first-class -sources in a .NET C# project.

- -

A Walkthrough

- -

In this blog post, we’ll walk through the simplest and probably the most common -scenario of creating a library from .proto files using the cross-platform -dotnet command. We will implement essentially a clone of the Greeter -library, shared by client and server projects in the C# Helloworld example -directory -.

- -

Create a new project

- -

Let’s start by creating a new library project.

-
~/work$ dotnet new classlib -o MyGreeter
-The template "Class library" was created successfully.
-
-~/work$ cd MyGreeter
-~/work/MyGreeter$ ls -lF
-total 12
--rw-rw-r-- 1 kkm kkm   86 Nov  9 16:10 Class1.cs
--rw-rw-r-- 1 kkm kkm  145 Nov  9 16:10 MyGreeter.csproj
-drwxrwxr-x 2 kkm kkm 4096 Nov  9 16:10 obj/
-

Observe that the dotnet new command has created the file Class1.cs that -we won’t need, so remove it. Also, we need some .proto files to compile. For -this exercise, we’ll copy an example file examples/protos/helloworld.proto - -from the gRPC distribution.

-
~/work/MyGreeter$ rm Class1.cs
-~/work/MyGreeter$ wget -q https://raw.githubusercontent.com/grpc/grpc/master/examples/protos/helloworld.proto
-

(on Windows, use del Class1.cs, and, if you do not have the wget command, -just open the above URL - -and use a Save As… command from your Web browser).

- -

Next, add required NuGet packages to the project:

-
~/work/MyGreeter$ dotnet add package Grpc
-info : PackageReference for package 'Grpc' version '1.17.0' added to file '/home/kkm/work/MyGreeter/MyGreeter.csproj'.
-~/work/MyGreeter$ dotnet add package Grpc.Tools
-info : PackageReference for package 'Grpc.Tools' version '1.17.0' added to file '/home/kkm/work/MyGreeter/MyGreeter.csproj'.
-~/work/MyGreeter$ dotnet add package Google.Protobuf
-info : PackageReference for package 'Google.Protobuf' version '3.6.1' added to file '/home/kkm/work/MyGreeter/MyGreeter.csproj'.
-

Add .proto files to the project

- -

Next comes an important part. First of all, by default, a .csproj project -file automatically finds all .cs files in its directory, although -Microsoft now recommends suppressing this globbing -behavior, -so we too decided against globbing .proto files. Thus the .proto -files must be added to the project explicitly.

- -

Second of all, it is important to add a property PrivateAssets="All" to the -Grpc.Tools package reference, so that it will not be needlessly fetched by the -consumers of your new library. This makes sense, as the package only contains -compilers, code generators and import files, which are not needed outside of -the project where the .proto files have been compiled. While not strictly -required in this simple walkthrough, it must be your standard practice to do -that always.

- -

So edit the file MyGreeter.csproj to add the helloworld.proto so that it -will be compiled, and the PrivateAssets property to the Grpc.Tools package -reference. Your resulting project file should now look like this:

-
<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Google.Protobuf" Version="3.6.1" />
-    <PackageReference Include="Grpc" Version="1.17.0" />
-
-    <!-- The Grpc.Tools package generates C# sources from .proto files during
-         project build, but is not needed by projects using the built library.
-         It's IMPORTANT to add the 'PrivateAssets="All"' to this reference: -->
-    <PackageReference Include="Grpc.Tools" Version="1.17.0" PrivateAssets="All" />
-
-    <!-- Explicitly include our helloworld.proto file by adding this line: -->
-    <Protobuf Include="helloworld.proto" />
-  </ItemGroup>
-
-</Project>
-

Build it!

- -

At this point you can build the project with the dotnet build command to -compile the .proto file and the library assembly. For this walkthrough, we’ll -add a logging switch -v:n to the command, so we can see that the command to -compile the helloworld.proto file was in fact run. You may find it a good -idea to always do that the very first time you compile a project!

- -

Note that many output lines are omitted below, as the build output is quite -verbose.

-
~/work/MyGreeter$ dotnet build -v:n
-
-Build started 11/9/18 5:33:44 PM.
-  1:7>Project "/home/kkm/work/MyGreeter/MyGreeter.csproj" on node 1 (Build target(s)).
-   1>_Protobuf_CoreCompile:
-      /home/kkm/.nuget/packages/grpc.tools/1.17.0/tools/linux_x64/protoc
-        --csharp_out=obj/Debug/netstandard2.0
-        --plugin=protoc-gen-grpc=/home/kkm/.nuget/packages/grpc.tools/1.17.0/tools/linux_x64/grpc_csharp_plugin
-        --grpc_out=obj/Debug/netstandard2.0 --proto_path=/home/kkm/.nuget/packages/grpc.tools/1.17.0/build/native/include
-        --proto_path=. --dependency_out=obj/Debug/netstandard2.0/da39a3ee5e6b4b0d_helloworld.protodep helloworld.proto
-     CoreCompile:
-
-        [ ... skipping long output ... ]
-
-       MyGreeter -> /home/kkm/work/MyGreeter/bin/Debug/netstandard2.0/MyGreeter.dll
-
-Build succeeded.
-

If at this point you invoke the dotnet build -v:n command again, protoc -would not be invoked, and no C# sources would be compiled. But if you change -the helloworld.proto source, then its outputs will be regenerated and then -recompiled by the C# compiler during the build. This is a regular dependency -tracking behavior that you expect from modifying any source file.

- -

Of course, you can also add .cs files to the same project: It is a regular C# -project building a .NET library, after all. This is done in our RouteGuide - -example.

- -

Where are the generated files?

- -

You may wonder where the proto compiler and gRPC plugin output C# files are. By -default, they are placed in the same directory as other generated files, such -as objects (termed the “intermediate output” directory in the .NET build -parlance), under the obj/ directory. This is a regular practice of .NET -builds, so that autogenerated files do not clutter the working directory or -accidentally placed under source control. Otherwise, they are accessible to the -tools like the debugger. You can see other autogenerated sources in that -directory, too:

-
~/work/MyGreeter$ find obj -name '*.cs'
-obj/Debug/netstandard2.0/MyGreeter.AssemblyInfo.cs
-obj/Debug/netstandard2.0/Helloworld.cs
-obj/Debug/netstandard2.0/HelloworldGrpc.cs
-

(use dir /s obj\*.cs if you are following this walkthrough from a Windows -command prompt).

- -

There Is More To It

- -

While the simplest default behavior is adequate in many cases, there are many -ways to fine-tune your .proto compilation process in a large project. We -encourage you to read the documentation file BUILD-INTEGRATION.md - -for available options if you find that the default arrangement does not suit -your workflow. The package also extends the Visual Studio’s Properties window, -so you may set some options per file in the Visual Studio interface.

- -

“Classic” .csproj projects and Mono are also supported.

- -

Share Your Experience

- -

As with any initial release of a complex feature, we are thrilled to receive -your feedback. Did something not work as expected? Do you have a scenario that -is not easy to cover with the new tools? Do you have an idea how to improve the -workflow in general? Please read the documentation carefully, and then open an -issue in the gRPC code repository on -GitHub. Your feedback is important to determine the future direction for our -build integration work!

-

- - -
- - - - - - - - - - diff --git a/public/blog/grpc-stacks/index.html b/public/blog/grpc-stacks/index.html deleted file mode 100644 index a8dc323..0000000 --- a/public/blog/grpc-stacks/index.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - Visualizing gRPC Language Stacks – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Visualizing gRPC Language Stacks

-
Posted on Tuesday, December 11, 2018 - by - - Carl Mastrangelo - -
-

-

Here is a high level overview of the gRPC Stacks. Each of the 10 default languages supported by gRPC has multiple layers, allowing you to customize what pieces you want in your application.

- -

There are three main stacks in gRPC: C-core, Go, and Java. Most of the languages are thin wrappers on top of the C-based gRPC core library:

- -

Wrapped Languages:

- -

gRPC Core Stack

- -

For example, a Python application calls into the generated Python stubs. These calls pass through interceptors, and into the wrapping library where the calls are translated into C calls. The gRPC C-core will encode the RPC as HTTP/2, optionally encrypt the data with TLS, and then write it to the network.

- -

One of the cool things about gRPC is that you can swap these pieces out. For example, you could use C# instead, and use an In-Process transport. This would save you from having to go all the way down to the OS network layer. Another example is trying out the QUIC protocol, which allows you to open new connections quickly. Being able to run over a variety of transports based on the environment makes gRPC really flexible.

- -

For each of the wrapped languages, the default HTTP/2 implementation is built into the C-core library, so there is no need to include an outside one. However, as you can see, it is possible to bring your own (such as with Cronet, the Chrome networking library).

- -

Go

- -

In gRPC-Go, the stack is much simpler, due to not having to support so many configurations. Here is a high level overview of the Go stack:

- -

gRPC Go Stack

- -

The structure is a little different here. Since there is only one language, the flow from the top of the stack to the bottom is more linear. Unlike wrapped languages, gRPC Go can use either its own HTTP/2 implementation, or the Go net/http package.

- -

Java

- -

Here is a high level overview of the gRPC-Java stack:

- -

gRPC Java Stack

- -

Again, the structure is a little different. Java supports HTTP/2, QUIC, and In Process like the C-core. Unlike the C-Core though, applications commonly can bypass the generated stubs and interceptors, and speak directly to the Java Core library. Each structure is slightly different based on the needs of each language implementation of gRPC. Also unlike wrapped languages, gRPC Java separates the HTTP/2 implementation into pluggable libraries (such as Netty, OkHttp, or Cronet).

-

- - -
- - - - - - - - - - diff --git a/public/blog/grpc-web-ga/index.html b/public/blog/grpc-web-ga/index.html deleted file mode 100644 index c9c3cd6..0000000 --- a/public/blog/grpc-web-ga/index.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - gRPC-Web is Generally Available – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC-Web is Generally Available

-
Posted on Tuesday, October 23, 2018 - by - - Luc Perkins - CNCF, Stanley Cheung - Google, Kailash Sethuraman - Google - -
-

-

We are excited to announce the GA release of -gRPC-Web, a JavaScript client library -that enables web apps to communicate directly with gRPC backend services, -without requiring an HTTP server to act as an intermediary. “GA” means that -gRPC-Web is now Generally Available and stable and qualified for production use.

- -

With gRPC-Web, you can now easily build truly end-to-end gRPC application -architectures by defining your client and server-side data types and service -interfaces with Protocol Buffers. This has been a hotly requested feature for a -while, and we are finally happy to say that it is now ready for production use. -In addition, being able to access gRPC services opens up new an exciting -possibilities for web based -tooling around gRPC.

- -

The Basics

- -

gRPC-Web, just like gRPC, lets you define the service “contract” between client -(web) and backend gRPC services using Protocol Buffers. The client can then be -auto generated. To do this, you have a choice between the Closure compiler -or the more widely used CommonJS. -This development process removes the need to manage concerns such as creating -custom JSON seralization and deserialization logic, wrangling HTTP status codes -(which can vary across REST APIs), managing content type negotiation etc.

- -

From a broader architectural perspective, gRPC-Web enables end-to-end gRPC. The diagram below illustrates this:

- -

- -

Figure 1. -gRPC with gRPC-Web (left) and gRPC with REST (right)

- -

In the gRPC-Web universe on the left, a client application speaks Protocol Buffers to a gRPC backend server that speaks Protocol Buffers to other gRPC backend services. In the REST universe on the right, the web app speaks HTTP to a backend REST API server that then speaks Protocol Buffers to backend services.

- -

Advantages of using gRPC-Web

- -

gRPC-Web will offer an ever-broader feature set over time, but here’s what’s in 1.0 today:

- - - -

A gRPC-Web example

- -

The previous section illustrated some of the high-level advantages of gRPC-Web for large-scale applications. Now let’s get closer to the metal with an example: a simple TODO app. In gRPC-Web you can start with a simple todos.proto definition like this:

-
syntax = "proto3";
-
-package todos;
-
-message Todo {
-  string content = 1;
-  bool finished = 2;
-}
-
-message GetTodoRequest {
-  int32 id = 1;
-}
-
-service TodoService {
-  rpc GetTodoById (GetTodoRequest) returns (Todo);
-} 
-

CommonJS client-side code can be generated from this .proto definition with the following command:

-
protoc echo.proto \
-  --js_out=import_style=commonjs:./output \
-  --grpc-web_out=import_style=commonjs:./output
-

Now, fetching a list of TODOs from a backend gRPC service is as simple as:

-
const {GetTodoRequest} = require('./todos_pb.js');
-const {TodoServiceClient} = require('./todos_grpc_web_pb.js');
-
-const todoService = new proto.todos.TodoServiceClient('http://localhost:8080');
-const todoId = 1234;
-
-var getTodoRequest = new proto.todos.GetTodoRequest();
-getTodoRequest.setId(todoId);
-
-var metadata = {};
-var getTodo = todoService.getTodoById(getTodoRequest, metadata, (err, response) => {
-  if (err) {
-    console.log(err);
-  } else {
-    const todo = response.todo();
-    if (todo == null) {
-      console.log(`A TODO with the ID ${todoId} wasn't found`);
-    } else {
-      console.log(`Fetched TODO with ID ${todoId}: ${todo.content()}`);
-    }
-  }
-});
-
-

Once you declare the data types and a service interface, gRPC-Web abstracts away all the boilerplate, leaving you with a clean and human-friendly API (essentially the same API as the current Node.js for gRPC API, just transferred to the client).

- -

On the backend, the gRPC server can be written in any language that supports gRPC, such as Go, Java, C++, Ruby, Node.js, and many others. The last piece of the puzzle is the service proxy. From the get-go, gRPC-Web will support Envoy as the default service proxy, which has a built-in envoy.grpc_web filter that you can apply with just a few lines of copy-and-pastable configuration.

- -

Next Steps

- -

Going GA means that the core building blocks are firmly in place and ready for usage in production web applications. But there’s still much more to come for gRPC-Web. Check out the official roadmap to see what the core team envisions for the near future.

- -

If you’re interested in contributing to gRPC-Web, there are a few things we would love community help with:

- - - -

We’d also love to get feature requests from the community. Currently the best way to make feature requests is to fill out the gRPC-Web roadmap features survey. When filling up the form, list features you’d like to see and also let us know if you’d like to contribute to the development of those features in the I’d like to contribute to section. The gRPC-Web engineers will be sure to take that information to heart over the course of the project’s development.

- -

Most importantly, we want to thank all the Alpha and Beta users who have given us feedback, bug reports and pull requests contributions over the course of the past year. We would certainly hope to maintain this momentum and make sure this project brings tangible benefits to the developer community.

-

- - -
- - - - - - - - - - diff --git a/public/blog/grpc-with-json/index.html b/public/blog/grpc-with-json/index.html deleted file mode 100644 index d43d389..0000000 --- a/public/blog/grpc-with-json/index.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - - - gRPC + JSON – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC + JSON

-
Posted on Wednesday, August 15, 2018 - by - - Carl Mastrangelo - -
-

-

So you’ve bought into this whole RPC thing and want to try it out, but aren’t quite sure about Protocol Buffers. Your existing code encodes your own objects, or perhaps you have code that needs a particular encoding. What to do?

- -

Fortunately, gRPC is encoding agnostic! You can still get a lot of the benefits of gRPC without using Protobuf. In this post we’ll go through how to make gRPC work with other encodings and types. Let’s try using JSON.

- -

gRPC is actually a collection of technologies that have high cohesion, rather than a singular, monolithic framework. This means its possible to swap out parts of gRPC and still take advantage of gRPC’s benefits. Gson is a popular library for Java for doing JSON encoding. Let’s remove all the protobuf related things and replace them with Gson:

-
- Protobuf wire encoding
-- Protobuf generated message types
-- gPRC generated stub types
-+ JSON wire encoding
-+ Gson message types
-
-

Previously, Protobuf and gRPC were generating code for us, but we would like to use our own types. Additionally, we are going to be using our own encoding too. Gson allows us to bring our own types in our code, but provides a way of serializing those types into bytes.

- -

Let’s continue with the Key-Value store service. We will be modifying the code used my previous So You Want to Optimize gRPC post.

- -

What is a Service Anyways?

- -

From the point of view of gRPC, a Service is a collection of Methods. In Java, a method is represented as a MethodDescriptor. Each MethodDescriptor includes the name of the method, a Marshaller for encoding requests, and a Marshaller for encoding responses. They also include additional detail, such as if the call is streaming or not. For simplicity, we’ll stick with unary RPCs which have a single request and single response.

- -

Since we won’t be generating any code, we’ll need to write the message classes ourselves. There are four methods, each which have a request and a response type. This means we need to make eight messages:

-
  static final class CreateRequest {
-    byte[] key;
-    byte[] value;
-  }
-
-  static final class CreateResponse {
-  }
-
-  static final class RetrieveRequest {
-    byte[] key;
-  }
-
-  static final class RetrieveResponse {
-    byte[] value;
-  }
-
-  static final class UpdateRequest {
-    byte[] key;
-    byte[] value;
-  }
-
-  static final class UpdateResponse {
-  }
-
-  static final class DeleteRequest {
-    byte[] key;
-  }
-
-  static final class DeleteResponse {
-  }
-

Because GSON uses reflection to determine how the fields in our classes map to the serialized JSON, we don’t need to annotate the messages.

- -

Our client and server logic will use the request and response types, but gRPC needs to know how to produce and consume these messages. To do this, we need to implement a Marshaller. A marshaller knows how to convert from an arbitrary type to an InputStream, which is then passed down into the gRPC core library. It is also capable of doing the reverse transformation when decoding data from the network. For GSON, here is what the marshaller looks like:

-
  static <T> Marshaller<T> marshallerFor(Class<T> clz) {
-    Gson gson = new Gson();
-    return new Marshaller<T>() {
-      @Override
-      public InputStream stream(T value) {
-        return new ByteArrayInputStream(gson.toJson(value, clz).getBytes(StandardCharsets.UTF_8));
-      }
-
-      @Override
-      public T parse(InputStream stream) {
-        return gson.fromJson(new InputStreamReader(stream, StandardCharsets.UTF_8), clz);
-      }
-    };
-  }
-

Given a Class object for a some request or response, this function will produce a marshaller. Using the marshallers, we can compose a full MethodDescriptor for each of the four CRUD methods. Here is an example of the Method descriptor for Create:

-
  static final MethodDescriptor<CreateRequest, CreateResponse> CREATE_METHOD =
-      MethodDescriptor.newBuilder(
-          marshallerFor(CreateRequest.class),
-          marshallerFor(CreateResponse.class))
-          .setFullMethodName(
-              MethodDescriptor.generateFullMethodName(SERVICE_NAME, "Create"))
-          .setType(MethodType.UNARY)
-          .build();
-

Note that if we were using Protobuf, we would use the existing Protobuf marshaller, and the -method descriptors -would be generated automatically.

- -

Sending RPCs

- -

Now that we can marshal JSON requests and responses, we need to update our -KvClient, -the gRPC client used in the previous post, to use our MethodDescriptors. Additionally, since we won’t be using any Protobuf types, the code needs to use ByteBuffer rather than ByteString. That said, we can still use the grpc-stub package on Maven to issue the RPC. Using the Create method again as an example, here’s how to make an RPC:

-
    ByteBuffer key = createRandomKey();
-    ClientCall<CreateRequest, CreateResponse> call =
-        chan.newCall(KvGson.CREATE_METHOD, CallOptions.DEFAULT);
-    KvGson.CreateRequest req = new KvGson.CreateRequest();
-    req.key = key.array();
-    req.value = randomBytes(MEAN_VALUE_SIZE).array();
-
-    ListenableFuture<CreateResponse> res = ClientCalls.futureUnaryCall(call, req);
-    // ...
-

As you can see, we create a new ClientCall object from the MethodDescriptor, create the request, and then send it using ClientCalls.futureUnaryCall in the stub library. gRPC takes care of the rest for us. You can also make blocking stubs or async stubs instead of future stubs.

- -

Receiving RPCs

- -

To update the server, we need to create a key-value service and implementation. Recall that in gRPC, a Server can handle one or more Services. Again, what Protobuf would normally have generated for us we need to write ourselves. Here is what the base service looks like:

-
  static abstract class KeyValueServiceImplBase implements BindableService {
-    public abstract void create(
-        KvGson.CreateRequest request, StreamObserver<CreateResponse> responseObserver);
-
-    public abstract void retrieve(/*...*/);
-
-    public abstract void update(/*...*/);
-
-    public abstract void delete(/*...*/);
-
-    /* Called by the Server to wire up methods to the handlers */
-    @Override
-    public final ServerServiceDefinition bindService() {
-      ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(SERVICE_NAME);
-      ssd.addMethod(CREATE_METHOD, ServerCalls.asyncUnaryCall(
-          (request, responseObserver) -> create(request, responseObserver)));
-
-      ssd.addMethod(RETRIEVE_METHOD, /*...*/);
-      ssd.addMethod(UPDATE_METHOD, /*...*/);
-      ssd.addMethod(DELETE_METHOD, /*...*/);
-      return ssd.build();
-    }
-  }
-

KeyValueServiceImplBase will serve as both the service definition (which describes which methods the server can handle) and as the implementation (which describes what to do for each method). It serves as the glue between gRPC and our application logic. Practically no changes are needed to swap from Proto to GSON in the server code:

-
final class KvService extends KvGson.KeyValueServiceImplBase {
-
-  @Override
-  public void create(
-      KvGson.CreateRequest request, StreamObserver<KvGson.CreateResponse> responseObserver) {
-    ByteBuffer key = ByteBuffer.wrap(request.key);
-    ByteBuffer value = ByteBuffer.wrap(request.value);
-    // ...
-  }
-

After implementing all the methods on the server, we now have a fully functioning gRPC Java, JSON encoding RPC system. And to show you there is nothing up my sleeve:

-
$ ./gradlew :dependencies | grep -i proto
-$ # no proto deps!
-

Optimizing the Code

- -

While Gson is not as fast as Protobuf, there’s no sense in not picking the low hanging fruit. Running the code we see the performance is pretty slow:

-
./gradlew installDist
-time ./build/install/kvstore/bin/kvstore
-
-INFO: Did 215.883 RPCs/s
-

What happened? In the previous optimization post, we saw the Protobuf version do nearly 2,500 RPCs/s. JSON is slow, but not that slow. We can see what the problem is by printing out the JSON data as it goes through the marshaller:

-
{"key":[4,-100,-48,22,-128,85,115,5,56,34,-48,-1,-119,60,17,-13,-118]}
-

That’s not right! Looking at a RetrieveRequest, we see that the key bytes are being encoded as an array, rather than as a byte string. The wire size is much larger than it needs to be, and may not be compatible with other JSON code. To fix this, let’s tell GSON to encode and decode this data as base64 encoded bytes:

-
  private static final Gson gson =
-      new GsonBuilder().registerTypeAdapter(byte[].class, new TypeAdapter<byte[]>() {
-    @Override
-    public void write(JsonWriter out, byte[] value) throws IOException {
-      out.value(Base64.getEncoder().encodeToString(value));
-    }
-
-    @Override
-    public byte[] read(JsonReader in) throws IOException {
-      return Base64.getDecoder().decode(in.nextString());
-    }
-  }).create();
-

Using this in our marshallers, we can see a dramatic performance difference:

-
./gradlew installDist
-time ./build/install/kvstore/bin/kvstore
-
-INFO: Did 2,202.2 RPCs/s
-

Almost 10x faster than before! We can still take advantage of gRPC’s efficiency while bringing our own encoders and messages.

- -

Conclusion

- -

gRPC lets you use encoders other than Protobuf. It has no dependency on Protobuf and was specially made to work with a wide variety of environments. We can see that with a little extra boilerplate, we can use any encoder we want. While this post only covered JSON, gRPC is compatible with Thrift, Avro, Flatbuffers, Cap’n Proto, and even raw bytes! gRPC lets you be in control of how your data is handled. (We still recommend Protobuf though due to strong backwards compatibility, type checking, and performance it gives you.)

- -

All the code is avaialable on GitHub if you would like to see a fully working implementation.

-

- - -
- - - - - - - - - - diff --git a/public/blog/grpc_on_http2/index.html b/public/blog/grpc_on_http2/index.html deleted file mode 100644 index a04d04a..0000000 --- a/public/blog/grpc_on_http2/index.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - - - - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

-
Posted on Monday, August 20, 2018 - by - - Jean de Klerk - -
-

-

In a previous article, we explored how HTTP/2 dramatically increases network efficiency and enables real-time communication by providing a framework for long-lived connections. In this article, we’ll look at how gRPC builds on HTTP/2’s long-lived connections to create a performant, robust platform for inter-service communication. We will explore the relationship between gRPC and HTTP/2, how gRPC manages HTTP/2 connections, and how gRPC uses HTTP/2 to keep connections alive, healthy, and utilized.

- -

gRPC Semantics

- -

To begin, let’s dive into how gRPC concepts relate to HTTP/2 concepts. gRPC introduces three new concepts: channels [1], remote procedure calls (RPCs), and messages. The relationship between the three is simple: each channel may have many RPCs while each RPC may have many messages.

- -

Channel Mapping

- -

Let’s take a look at how gRPC semantics relate to HTTP/2:

- -

gRPC on HTTP/2

- -

Channels are a key concept in gRPC. Streams in HTTP/2 enable multiple concurrent conversations on a single connection; channels extend this concept by enabling multiple streams over multiple concurrent connections. On the surface, channels provide an easy interface for users to send messages into; underneath the hood, though, an incredible amount of engineering goes into keeping these connections alive, healthy, and utilized.

- -

Channels represent virtual connections to an endpoint, which in reality may be backed by many HTTP/2 connections. RPCs are associated with a connection (this association is described further on). RPCs are in practice plain HTTP/2 streams. Messages are associated with RPCs and get sent as HTTP/2 data frames. To be more specific, messages are layered on top of data frames. A data frame may have many gRPC messages, or if a gRPC message is quite large [2] it might span multiple data frames.

- -

Resolvers and Load Balancers

- -

In order to keep connections alive, healthy, and utilized, gRPC utilizes a number of components, foremost among them name resolvers and load balancers. The resolver turns names into addresses and then hands these addresses to the load balancer. The load balancer is in charge of creating connections from these addresses and load balancing RPCs between connections.

- -

Resolvers and Load Balancers

- -

Round Robin Load Balancer

- -

A DNS resolver, for example, might resolve some host name to 13 IP addresses, and then a RoundRobin balancer might create 13 connections - one to each address - and round robin RPCs across each connection. A simpler balancer might simply create a connection to the first address. Alternatively, a user who wants multiple connections but knows that the host name will only resolve to one address might have their balancer create connections against each address 10 times to ensure that multiple connections are used.

- -

Resolvers and load balancers solve small but crucial problems in a gRPC system. This design is intentional: reducing the problem space to a few small, discrete problems helps users build custom components. These components can be used to fine-tune gRPC to fit each system’s individual needs.

- -

Connection Management

- -

Once configured, gRPC will keep the pool of connections - as defined by the resolver and balancer - healthy, alive, and utilized.

- -

When a connection fails, the load balancer will begin to reconnect using the last known list of addresses [3]. Meanwhile, the resolver will begin attempting to re-resolve the list of host names. This is useful in a number of scenarios. If the proxy is no longer reachable, for example, we’d want the resolver to update the list of addresses to not include that proxy’s address. To take another example: DNS entries might change over time, and so the list of addresses might need to be periodically updated. In this manner and others, gRPC is designed for long-term resiliency.

- -

Once resolution is finished, the load balancer is informed of the new addresses. If addresses have changed, the load balancer may spin down connections to addresses not present in the new list or create connections to addresses that weren’t previously there.

- -

Identifying Failed Connections

- -

The effectiveness of gRPC’s connection management hinges upon its ability to identify failed connections. There are generally two types of connection failures: clean failures, in which the failure is communicated, and the less-clean failure, in which the failure is not communicated.

- -

Let’s consider a clean, easy-to-observe failure. Clean failures can occur when an endpoint intentionally kills the connection. For example, the endpoint may have gracefully shut down, or a timer may have been exceeded, prompting the endpoint to close the connection. When connections close cleanly, TCP semantics suffice: closing a connection causes the FIN handshake to occur. This ends the HTTP/2 connection, which ends the gRPC connection. gRPC will immediately begin reconnecting (as described above). This is quite clean and requires no additional HTTP/2 or gRPC semantics.

- -

The less clean version is where the endpoint dies or hangs without informing the client. In this case, TCP might undergo retry for as long as 10 minutes before the connection is considered failed. Of course, failing to recognize that the connection is dead for 10 minutes is unacceptable. gRPC solves this problem using HTTP/2 semantics: when configured using KeepAlive, gRPC will periodically send HTTP/2 PING frames. These frames bypass flow control and are used to establish whether the connection is alive. If a PING response does not return within a timely fashion, gRPC will consider the connection failed, close the connection, and begin reconnecting (as described above).

- -

In this way, gRPC keeps a pool of connections healthy and uses HTTP/2 to ascertain the health of connections periodically. All of this behavior is opaque to the user, and message redirecting happens automatically and on the fly. Users simply send messages on a seemingly always-healthy pool of connections.

- -

Keeping Connections Alive

- -

As mentioned above, KeepAlive provides a valuable benefit: periodically checking the health of the connection by sending an HTTP/2 PING to determine whether the connection is still alive. However, it has another equally useful benefit: signaling liveness to proxies.

- -

Consider a client sending data to a server through a proxy. The client and server may be happy to keep a connection alive indefinitely, sending data as necessary. Proxies, on the other hand, are often quite resource constrained and may kill idle connections to save resources. Google Cloud Platform (GCP) load balancers disconnect apparently-idle connections after 10 minutes, and Amazon Web Services Elastic Load Balancers (AWS ELBs) disconnect them after 60 seconds.

- -

With gRPC periodically sending HTTP/2 PING frames on connections, the perception of a non-idle connection is created. Endpoints using the aforementioned idle kill rule would pass over killing these connections.

- -

A Robust, High Performance Protocol

- -

HTTP/2 provides a foundation for long-lived, real-time communication streams. gRPC builds on top of this foundation with connection pooling, health semantics, efficient use of data frames and multiplexing, and KeepAlive.

- -

Developers choosing protocols must choose those that meet today’s demands as well as tomorrow’s. They are well served by choosing gRPC, whether it be for resiliency, performance, long-lived or short-lived communication, customizability, or simply knowing that their protocol will scale to extraordinarily massive traffic while remaining efficient all the way. To get going with gRPC and HTTP/2 right away, check out gRPC’s Getting Started guides.

- -

Footnotes

- -
    -
  1. In Go, a gRPC channel is called ClientConn because the word “channel” has a language-specific meaning.
  2. -
  3. gRPC uses the HTTP/2 default max size for a data frame of 16kb. A message over 16kb may span multiple data frames, whereas a message below that size may share a data frame with some number of other messages.
  4. -
  5. This is the behavior of the RoundRobin balancer, but not every load balancer does or must behave this way.
  6. -
-

- - -
- - - - - - - - - - diff --git a/public/blog/hello-pancakes/index.html b/public/blog/hello-pancakes/index.html deleted file mode 100644 index b1a7e16..0000000 --- a/public/blog/hello-pancakes/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - Dear gRPC – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Dear gRPC

-
Posted on Friday, March 08, 2019 - by - - April Nassi - -
-

-

Dear gRPC,

- -

We messed up. We are so sorry that we missed your birthday this year. Last year we celebrated with cake and fanfare, but this year we dropped the ball. Please don’t think that we love you any less.

- -

You’re 4 now and that’s a big milestone! You’re part of so much amazing technology at companies like Salesforce, Netflix, Spotify, Fanatics, and of course, Google. In fact just this week the biggest API Google has went production-ready with gRPC.

- -

We’re proud of you, gRPC, and we’re going to make this up to you. For starters - we got you a puppy! He’s an adorable Golden Retriever and his name is PanCakes. He loves to run back and forth with toys, packets, or messages. He’s super active and no matter how much we train him, we just can’t get him to REST. PanCakes is going to be your best friend, and ambassador.

- -

gRPC Mascot PanCakes

- -

Even though it’s a bit late, we still want to throw you a party, gRPC. Our friends at CNCF have planned a big event for you on March 21, and there’s going to be lots of people there! They’ll be sharing stories about the cool things they’ve built, and meeting new people. It’s an entire day all about you, and everyone there is going to learn so much. There will be other puppies who can play with PanCakes! Some of the amazing dogs from Canine Companions for Independence will be there to greet conference attendees and share how they help their humans live a more independent life.

- -

We are so excited to see what this year holds for you, gRPC!

- -

~ gRPC Maintainers

- -

gRPC Mascot PanCakes

- -

- - -
- - - - - - - - - - diff --git a/public/blog/helmgrpc/index.html b/public/blog/helmgrpc/index.html deleted file mode 100644 index 2391783..0000000 --- a/public/blog/helmgrpc/index.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - gRPC in Helm – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC in Helm

-
Posted on Monday, May 15, 2017 - by - - Brian Hardock - -
-

-

Our guest post today comes from Brian Hardock, a software engineer from Deis working on the Helm project.

- -

Helm is the package manager for Kubernetes. Helm provides its users with a customizable mechanism for -managing distributed applications and controlling their deployment.

- -

I have the good fortune to be a member of the phenomenal open-source Kubernetes Helm community serving as -a core contributor. My first day working with the Helm team was spent prototyping the architecture for -the next generation of Helm. By the end of that day, we had procured the preliminary RPC protocol data model -used to enable communication between Helm and its in-cluster server component, Tiller.

- -

We chose to use protocol buffers - the default framework gRPC uses for serialization and over-the-air -transmission - as our data definition language. By the end of that first day hacking with the Helm team, -gRPC and protocol buffers proved to be a powerful combination. We had successfully had acheived communication -between the Helm client and Tiller server using code generated from the protobuf and gRPC service definitions. -As a personal preference, we found that the protobuf files and resulting generated gRPC -code provided an aesthetic, nearly self-documenting developer experience compared to something like Swagger.

- -

Within a few days, the Helm team was scoping and implementing features for our users. By choosing gRPC/Proto -we had reduced the typical time spent bikeshedding that, in general, inevitably evolves from API modeling and -churning out boilerplate server code. If we had not reaped the benefits of gRPC/protobuf from day 1, we would -have spent significantly more time pivoting up and down the stack, as opposed to honing our focus on what -matters: the users and the features they requested.

- -

In addition to serving as the Helm/Tiller communication protocol, one of our more interesting applications -of protocol buffers is that we use it to model what’s referred to in Kubernetes parlance as a “Chart”. Charts -are an encapsulation of Kubernetes manifests that enable you to define, install, and upgrade Kubernetes applications. -For more complex Kubernetes applications, the set of manifests may be large. By virtue of its inherent compression -capabilities, protocol buffers and gRPC allowed us to mitigate the nuisance of transmitting bulky and -sprawling Kubernetes manifests.

- -

For a deeper dive into:

- - - -

In summary, protobuf and gRPC provided Helm with:

- - -

- - -
- - - - - - - - - - diff --git a/public/blog/http2_smarter_at_scale/index.html b/public/blog/http2_smarter_at_scale/index.html deleted file mode 100644 index 02f231a..0000000 --- a/public/blog/http2_smarter_at_scale/index.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - HTTP/2 Smarter At Scale – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

HTTP/2 Smarter At Scale

-
Posted on Friday, July 13, 2018 - by - - Jean de Klerk - -
-

-

Much of the web today runs on HTTP/1.1. The spec for HTTP/1.1 was published in June of 1999, just shy of 20 years ago. A lot has changed since then, which makes it all the more remarkable that HTTP/1.1 has persisted and flourished for so long. But in some areas it’s beginning to show its age; for the most part, in that the designers weren’t building for the scale at which HTTP/1.1 would be used and the astonishing amount of traffic that it would come to handle. A not-so-bad case is that subsequent tests can’t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn’t have passed at all if the previously passed test had not leaked a resource.

- -

HTTP/2, whose specification was published in May of 2015, seeks to address some of the scalability concerns of its predecessor while still providing a similar experience to users. HTTP/2 improves upon HTTP/1.1’s design in a number of ways, perhaps most significantly in providing a semantic mapping over connections. In this post we’ll explore the concept of streams and how they can be of substantial benefit to software engineers.

- -

Semantic Mapping over Connections

- -

There’s significant overhead to creating HTTP connections. You must establish a TCP connection, secure that connection using TLS, exchange headers and settings, and so on. HTTP/1.1 simplified this process by treating connections as long-lived, reusable objects. HTTP/1.1 connections are kept idle so that new requests to the same destination can be sent over an existing, idle connection. Though connection reuse mitigates the problem, a connection can only handle one request at a time - they are coupled 1:1. If there is one large message being sent, new requests must either wait for its completion (resulting in head-of-line blocking) or, more frequently, pay the price of spinning up another connection.

- -

HTTP/2 takes the concept of persistent connections further by providing a semantic layer above connections: streams. Streams can be thought of as a series of semantically connected messages, called frames. A stream may be short-lived, such as a unary stream that requests the status of a user (in HTTP/1.1, this might equate to GET /users/1234/status). With increasing frequency it’s long-lived. To use the last example, instead of making individual requests to the /users/1234/status endpoint, a receiver might establish a long-lived stream and thereby continuously receive user status messages in real time.

- -

Kotlin Android app example

- -

Streams Provide Concurrency

- -

The primary advantage of streams is connection concurrency, i.e. the ability to interleave messages on a single connection.

- -

To illustrate this point, consider the case of some service A sending HTTP/1.1 requests to some service B about new users, profile updates, and product orders. Product orders tend to be large, and each product order ends up being broken up and sent as 5 TCP packets (to illustrate its size). Profile updates are very small and fit into one packet; new user requests are also small and fit into two packets.

- -

In some snapshot in time, service A has a single idle connection to service B and wants to use it to send some data. Service A wants to send a product order (request 1), a profile update (request 2), and two “new user” requests (requests 3 and 4). Since the product order arrives first, it dominates the single idle connection. The latter three smaller requests must either wait for the large product order to be sent, or some number of new HTTP/1.1 connection must be spun up for the small requests.

- -

Kotlin Android app example

- -

Meanwhile, with HTTP/2, streaming allows messages to be sent concurrently on the same connection. Let’s imagine that service A creates a connection to service B with three streams: a “new users” stream, a “profile updates” stream, and a “product order” stream. Now, the latter requests don’t have to wait for the first-to-arrive large product order request; all requests are sent concurrently.

- -

Concurrency does not mean parallelism, though; we can only send one packet at a time on the connection. So, the sender might round robin sending packets between streams (see below). Alternatively, senders might prioritize certain streams over others; perhaps getting new users signed up is more important to the service!

- -

Kotlin Android app example

- -

Flow Control

- -

Concurrent streams, however, harbor some subtle gotchas. Consider the following situation: two streams A and B on the same connection. Stream A receives a massive amount of data, far more than it can process in a short amount of time. Eventually the receiver’s buffer fills up and the TCP receive window limits the sender. This is all fairly standard behavior for TCP, but this situation is bad for streams as neither streams would receive any more data. Ideally stream B should be unaffected by stream A’s slow processing.

- -

HTTP/2 solves this problem by providing a flow control mechanism as part of the stream specification. Flow control is used to limit the amount of outstanding data on a per-stream (and per-connection) basis. It operates as a credit system in which the receiver allocates a certain “budget” and the sender “spends” that budget. More specifically, the receiver allocates some buffer size (the “budget”) and the sender fills (“spends”) the buffer by sending data. The receiver advertises to the sender additional buffer as it is made available, using special-purpose WINDOW_UPDATE frames. When the receiver stops advertising additional buffer, the sender must stop sending messages when the buffer (its “budget”) is exhausted.

- -

Using flow control, concurrent streams are guaranteed independent buffer allocation. Coupled with round robin request sending, streams of all sizes, processing speeds, and duration may be multiplexed on a single connection without having to care about cross-stream problems.

- -

Smarter Proxies

- -

The concurrency properties of HTTP/2 allow proxies to be more performant. As an example, consider an HTTP/1.1 load balancer that accepts and forwards spiky traffic: when a spike occurs, the proxy spins up more connections to handle the load or queues the requests. The former - new connections - are typically preferred (to a point); the downside to these new connections is paid not just in time waiting for syscalls and sockets, but also in time spent underutilizing the connection whilst TCP slow-start occurs.

- -

In contrast, consider an HTTP/2 proxy that is configured to multiplex 100 streams per connection. A spike of some amount of requests will still cause new connections to be spun up, but only 1100 connections as compared to its HTTP/1.1 counterpart. More generally speaking: If n HTTP/1.1 requests are sent to a proxy, n HTTP/1.1 requests must go out; each request is a single, meaningful request/payload of data, and requests are 1:1 with connections. In contrast, with HTTP/2 n requests sent to a proxy require n streams, but there is no requirement of n connections!

- -

The proxy has room to make a wide variety of smart interventions. It may, for example:

- - - -

HTTP/2 Is Smarter At Scale

- -

HTTP/2 has many advantages over HTTP/1.1 that dramatically reduce the network cost of large-scale, real-time systems. Streams present one of the biggest flexibility and performance improvements that users will see, but HTTP/2 also provides semantics around graceful close (see: GOAWAY), header compression, server push, pinging, stream priority, and more. Check out the HTTP/2 spec if you’re interested in digging in more - it is long but rather easy reading.

- -

To get going with HTTP/2 right away, check out gRPC, a high-performance, open-source universal RPC framework that uses HTTP/2. In a future post we’ll dive into gRPC and explore how it makes use of the mechanics provided by HTTP/2 to provide incredibly performant communication at scale.

-

- - -
- - - - - - - - - - diff --git a/public/blog/index.html b/public/blog/index.html deleted file mode 100644 index fa848ac..0000000 --- a/public/blog/index.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - - - - Blogs – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- - -
-
- - -

Dear gRPC

-
March 08, 2019
-

- Dear gRPC, -We messed up. We are so sorry that we missed your birthday this year. Last year we celebrated with cake and fanfare, but this year we dropped the ball. Please don’t think that we love you any less. -You’re 4 now and that’s a big milestone! You’re part of so much amazing technology at companies like Salesforce, Netflix, Spotify, Fanatics, and of course, Google. In fact just this week the biggest API Google has went production-ready with gRPC. -

- -Read More -


- -

The state of gRPC in the browser

-
January 08, 2019
-

-

This is a guest post by -Johan Brandhorst, Software Engineer at -InfoSum.

- -

gRPC 1.0 was released in August 2016 and has since grown to become one of the -premier technical solutions for application communications. It has been adopted -by startups, enterprise companies, and open source projects worldwide. -Its support for polyglot environments, focus on performance, type safety, and -developer productivity has transformed the way developers design their -architectures.

- -

So far the benefits have largely only been available to mobile -app and backend developers, whilst frontend developers have had to continue to -rely on JSON REST interfaces as their primary means of information exchange. -However, with the release of gRPC-Web, gRPC is poised to become a valuable -addition in the toolbox of frontend developers.

- -

In this post, I’ll describe some of the history of gRPC in the browser, explore -the state of the world today, and share some thoughts on the future.

-

- -Read More -


- -

gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

-
December 18, 2018
-

-

As part of Microsoft’s move towards its cross-platform .NET offering, they have -greatly simplified the project file format, and allowed a tight integration of -third-party code generators with .NET projects. We are listening, and now proud -to introduce integrated compilation of Protocol Buffer and gRPC service -.proto files in .NET C# projects starting with the version 1.17 of the -Grpc.Tools NuGet package, now available from Nuget.org.

- -

You no longer need to use hand-written scripts to generate code from .proto -files: The .NET build magic handles this for you. The integrated tools locate -the proto compiler and gRPC plugin, standard Protocol Buffer imports, and track -dependencies before invoking the code generators, so that the generated C# -source files are never out of date, at the same time keeping regeneration to -the minimum required. In essence, .proto files are treated as first-class -sources in a .NET C# project.

-

- -Read More -


- -

Visualizing gRPC Language Stacks

-
December 11, 2018
-

-

Here is a high level overview of the gRPC Stacks. Each of the 10 default languages supported by gRPC has multiple layers, allowing you to customize what pieces you want in your application.

-

- -Read More -


- -

gRPC-Web is Generally Available

-
October 23, 2018
-

-

We are excited to announce the GA release of -gRPC-Web, a JavaScript client library -that enables web apps to communicate directly with gRPC backend services, -without requiring an HTTP server to act as an intermediary. “GA” means that -gRPC-Web is now Generally Available and stable and qualified for production use.

-

- -Read More -


- -

A short introduction to Channelz

-
September 05, 2018
-

-

Channelz is a tool that provides comprehensive runtime info about connections at -different levels in gRPC. It is designed to help debug live programs, which may -be suffering from network, performance, configuration issues, etc. The -gRFC provides a -detailed explanation of channelz design and is the canonical reference for all -channelz implementations across languages. The purpose of this blog is to -familiarize readers with channelz service and how to use it for debugging -issues. The context of this post is set in -gRPC-Go, but the overall idea should be -applicable across languages. At the time of writing, channelz is available for -gRPC-Go and -gRPC-Java. Support for -C++ and wrapped languages is coming soon.

-

- -Read More -


- -

gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

-
August 20, 2018
-

-

In a previous article, we explored how HTTP/2 dramatically increases network efficiency and enables real-time communication by providing a framework for long-lived connections. In this article, we’ll look at how gRPC builds on HTTP/2’s long-lived connections to create a performant, robust platform for inter-service communication. We will explore the relationship between gRPC and HTTP/2, how gRPC manages HTTP/2 connections, and how gRPC uses HTTP/2 to keep connections alive, healthy, and utilized.

-

- -Read More -


- -

gRPC + JSON

-
August 15, 2018
-

-

So you’ve bought into this whole RPC thing and want to try it out, but aren’t quite sure about Protocol Buffers. Your existing code encodes your own objects, or perhaps you have code that needs a particular encoding. What to do?

- -

Fortunately, gRPC is encoding agnostic! You can still get a lot of the benefits of gRPC without using Protobuf. In this post we’ll go through how to make gRPC work with other encodings and types. Let’s try using JSON.

-

- -Read More -


- -

Take the gRPC Survey!

-
August 14, 2018
-

-

The gRPC Project wants your feedback!

- -

The gRPC project is looking for feedback to improve the gRPC experience. To do this, we are running a gRPC user survey. We invite you to participate and provide input that will help us better plan and prioritize.

-

- -Read More -


- -

HTTP/2 Smarter At Scale

-
July 13, 2018
-

-

Much of the web today runs on HTTP/1.1. The spec for HTTP/1.1 was published in June of 1999, just shy of 20 years ago. A lot has changed since then, which makes it all the more remarkable that HTTP/1.1 has persisted and flourished for so long. But in some areas it’s beginning to show its age; for the most part, in that the designers weren’t building for the scale at which HTTP/1.1 would be used and the astonishing amount of traffic that it would come to handle. A not-so-bad case is that subsequent tests can’t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn’t have passed at all if the previously passed test had not leaked a resource.

-

- -Read More -


- - - - - -
- - - -
- -
All blog posts
- - Dear gRPC

- - The state of gRPC in the browser

- - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

- - Visualizing gRPC Language Stacks

- - gRPC-Web is Generally Available

- - A short introduction to Channelz

- - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

- - gRPC + JSON

- - Take the gRPC Survey!

- - HTTP/2 Smarter At Scale

- - Gracefully clean up in gRPC JUnit tests

- - gRPC ❤ Kotlin

- - So You Want to Optimize gRPC - Part 2

- - So You Want to Optimize gRPC - Part 1

- - gRPC and Deadlines

- - 2018-01-19 gRPC-Go Engineering Practices

- - The gRPC Meetup Kit

- - 2017-08-22 gRPC-Go performance Improvements

- - 2017-08-17 Community Meeting Update

- - Announcing out of the box support for gRPC in the Flatbuffers serialization library.

- - gRPC Load Balancing

- - gRPC in Helm

- - Migration to Google Cloud Platform — gRPC & grpc-gateway

- - Building gRPC services with bazel and rules_protobuf

- - gRPC at VSCO

- - Why we have decided to move our APIs to gRPC

- - gRPC Project is now 1.0 and ready for production deployments

- - gRPC with REST and Open APIs

- - gRPC - now with easy installation.

- - Google Cloud PubSub - with the power of gRPC!

- - gRPC releases Beta, opening door for use in production environments.

- - gRPC Motivation and Design Principles.

- - -
- - - -
- - - - - - - - - - - diff --git a/public/blog/index.xml b/public/blog/index.xml deleted file mode 100644 index 2bb3dd4..0000000 --- a/public/blog/index.xml +++ /dev/null @@ -1,424 +0,0 @@ - - - - Blogs on gRPC - https://cjyabraham.github.io/blog/ - Recent content in Blogs on gRPC - Hugo -- gohugo.io - en-us - Fri, 08 Mar 2019 00:00:00 +0000 - - - - - - Dear gRPC - https://cjyabraham.github.io/blog/hello-pancakes/ - Fri, 08 Mar 2019 00:00:00 +0000 - - https://cjyabraham.github.io/blog/hello-pancakes/ - Dear gRPC, -We messed up. We are so sorry that we missed your birthday this year. Last year we celebrated with cake and fanfare, but this year we dropped the ball. Please don&rsquo;t think that we love you any less. -You&rsquo;re 4 now and that&rsquo;s a big milestone! You&rsquo;re part of so much amazing technology at companies like Salesforce, Netflix, Spotify, Fanatics, and of course, Google. In fact just this week the biggest API Google has went production-ready with gRPC. - - - - The state of gRPC in the browser - https://cjyabraham.github.io/blog/state-of-grpc-web/ - Tue, 08 Jan 2019 00:00:00 +0000 - - https://cjyabraham.github.io/blog/state-of-grpc-web/ - <p><em>This is a guest post by</em> -<em><a href="https://jbrandhorst.com">Johan Brandhorst</a>, Software Engineer at</em> -<em><a href="https://www.infosum.com">InfoSum</a>.</em></p> - -<p>gRPC 1.0 was released in August 2016 and has since grown to become one of the -premier technical solutions for application communications. It has been adopted -by startups, enterprise companies, and open source projects worldwide. -Its support for polyglot environments, focus on performance, type safety, and -developer productivity has transformed the way developers design their -architectures.</p> - -<p>So far the benefits have largely only been available to mobile -app and backend developers, whilst frontend developers have had to continue to -rely on JSON REST interfaces as their primary means of information exchange. -However, with the release of gRPC-Web, gRPC is poised to become a valuable -addition in the toolbox of frontend developers.</p> - -<p>In this post, I&rsquo;ll describe some of the history of gRPC in the browser, explore -the state of the world today, and share some thoughts on the future.</p> - - - - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build - https://cjyabraham.github.io/blog/grpc-dotnet-build/ - Tue, 18 Dec 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/grpc-dotnet-build/ - <p>As part of Microsoft&rsquo;s move towards its cross-platform .NET offering, they have -greatly simplified the project file format, and allowed a tight integration of -third-party code generators with .NET projects. We are listening, and now proud -to introduce integrated compilation of Protocol Buffer and gRPC service -<code>.proto</code> files in .NET C# projects starting with the version 1.17 of the -Grpc.Tools NuGet package, now available from Nuget.org.</p> - -<p>You no longer need to use hand-written scripts to generate code from <code>.proto</code> -files: The .NET build magic handles this for you. The integrated tools locate -the proto compiler and gRPC plugin, standard Protocol Buffer imports, and track -dependencies before invoking the code generators, so that the generated C# -source files are never out of date, at the same time keeping regeneration to -the minimum required. In essence, <code>.proto</code> files are treated as first-class -sources in a .NET C# project.</p> - - - - Visualizing gRPC Language Stacks - https://cjyabraham.github.io/blog/grpc-stacks/ - Tue, 11 Dec 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/grpc-stacks/ - <p>Here is a high level overview of the gRPC Stacks. Each of the <strong>10</strong> default languages supported by gRPC has multiple layers, allowing you to customize what pieces you want in your application.</p> - - - - gRPC-Web is Generally Available - https://cjyabraham.github.io/blog/grpc-web-ga/ - Tue, 23 Oct 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/grpc-web-ga/ - <p>We are excited to announce the GA release of -<a href="https://www.npmjs.com/package/grpc-web">gRPC-Web</a>, a JavaScript client library -that enables web apps to communicate directly with gRPC backend services, -without requiring an HTTP server to act as an intermediary. &ldquo;GA&rdquo; means that -gRPC-Web is now Generally Available and stable and qualified for production use.</p> - - - - A short introduction to Channelz - https://cjyabraham.github.io/blog/a_short_introduction_to_channelz/ - Wed, 05 Sep 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/a_short_introduction_to_channelz/ - <p>Channelz is a tool that provides comprehensive runtime info about connections at -different levels in gRPC. It is designed to help debug live programs, which may -be suffering from network, performance, configuration issues, etc. The -<a href="https://github.com/grpc/proposal/blob/master/A14-channelz.md">gRFC</a> provides a -detailed explanation of channelz design and is the canonical reference for all -channelz implementations across languages. The purpose of this blog is to -familiarize readers with channelz service and how to use it for debugging -issues. The context of this post is set in -<a href="https://github.com/grpc/grpc-go">gRPC-Go</a>, but the overall idea should be -applicable across languages. At the time of writing, channelz is available for -<a href="https://github.com/grpc/grpc-go">gRPC-Go</a> and -<a href="https://github.com/grpc/grpc-java">gRPC-Java</a>. Support for -<a href="https://github.com/grpc/grpc">C++</a> and wrapped languages is coming soon.</p> - - - - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol - https://cjyabraham.github.io/blog/grpc_on_http2/ - Mon, 20 Aug 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/grpc_on_http2/ - <p>In a <a href="https://cjyabraham.github.io/blog/http2_smarter_at_scale">previous article</a>, we explored how HTTP/2 dramatically increases network efficiency and enables real-time communication by providing a framework for long-lived connections. In this article, we’ll look at how gRPC builds on HTTP/2’s long-lived connections to create a performant, robust platform for inter-service communication. We will explore the relationship between gRPC and HTTP/2, how gRPC manages HTTP/2 connections, and how gRPC uses HTTP/2 to keep connections alive, healthy, and utilized.</p> - - - - gRPC + JSON - https://cjyabraham.github.io/blog/grpc-with-json/ - Wed, 15 Aug 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/grpc-with-json/ - <p>So you&rsquo;ve bought into this whole RPC thing and want to try it out, but aren&rsquo;t quite sure about Protocol Buffers. Your existing code encodes your own objects, or perhaps you have code that needs a particular encoding. What to do?</p> - -<p>Fortunately, gRPC is encoding agnostic! You can still get a lot of the benefits of gRPC without using Protobuf. In this post we&rsquo;ll go through how to make gRPC work with other encodings and types. Let&rsquo;s try using JSON.</p> - - - - Take the gRPC Survey! - https://cjyabraham.github.io/blog/take-the-grpc-survey/ - Tue, 14 Aug 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/take-the-grpc-survey/ - <h2 id="the-grpc-project-wants-your-feedback">The gRPC Project wants your feedback!</h2> - -<p>The gRPC project is looking for feedback to improve the gRPC experience. To do this, we are running a <a href="http://bit.ly/gRPC18survey">gRPC user survey</a>. We invite you to participate and provide input that will help us better plan and prioritize.</p> - - - - HTTP/2 Smarter At Scale - https://cjyabraham.github.io/blog/http2_smarter_at_scale/ - Fri, 13 Jul 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/http2_smarter_at_scale/ - <p>Much of the web today runs on HTTP/1.1. The spec for HTTP/1.1 was published in June of 1999, just shy of 20 years ago. A lot has changed since then, which makes it all the more remarkable that HTTP/1.1 has persisted and flourished for so long. But in some areas it’s beginning to show its age; for the most part, in that the designers weren’t building for the scale at which HTTP/1.1 would be used and the astonishing amount of traffic that it would come to handle. A not-so-bad case is that subsequent tests can&rsquo;t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn&rsquo;t have passed at all if the previously passed test had not leaked a resource.</p> - - - - Gracefully clean up in gRPC JUnit tests - https://cjyabraham.github.io/blog/gracefully_clean_up_in_grpc_junit_tests/ - Tue, 26 Jun 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/gracefully_clean_up_in_grpc_junit_tests/ - <p>It is best practice to always clean up gRPC resources such as client channels, servers, and previously attached Contexts whenever they are no longer needed.</p> - -<p>This is even true for JUnit tests, because otherwise leaked resources may not only linger in your machine forever, but also interfere with subsequent tests. A not-so-bad case is that subsequent tests can&rsquo;t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn&rsquo;t have passed at all if the previously passed test had not leaked a resource.</p> - - - - gRPC ❤ Kotlin - https://cjyabraham.github.io/blog/kotlin-gradle-projects/ - Tue, 19 Jun 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/kotlin-gradle-projects/ - <p>Did you know that gRPC Java now has out of box support for Kotlin projects built with Gradle? <a href="https://kotlinlang.org/">Kotlin</a> is a modern, statically typed language developed by JetBrains that targets the JVM and Android. It is generally easy for Kotlin programs to interoperate with existing Java libraries. To improve this experience further, we have added support to the <a href="https://github.com/google/protobuf-gradle-plugin/releases">protobuf-gradle-plugin</a> so that the generated Java libraries are automatically picked up by Kotlin. You can now add the protobuf-gradle-plugin to your Kotlin project, and use gRPC just like you would with a typical Java project.</p> - - - - So You Want to Optimize gRPC - Part 2 - https://cjyabraham.github.io/blog/optimizing-grpc-part-2/ - Mon, 16 Apr 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/optimizing-grpc-part-2/ - <p>How fast is gRPC? Pretty fast if you understand how modern clients and servers are built. In -<a href="https://cjyabraham.github.io/blog/optimizing-grpc-part-1">part 1</a>, I showed how to get an easy <strong>60%</strong> improvement. In this -post I show how to get a <strong>10000%</strong> improvement.</p> - - - - So You Want to Optimize gRPC - Part 1 - https://cjyabraham.github.io/blog/optimizing-grpc-part-1/ - Tue, 06 Mar 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/optimizing-grpc-part-1/ - <p>A common question with gRPC is how to make it fast. The gRPC library offers users access to high -performance RPCs, but it isn&rsquo;t always clear how to achieve this. Because this question is common -enough I thought I would try to show my thought process when tuning programs.</p> - - - - gRPC and Deadlines - https://cjyabraham.github.io/blog/deadlines/ - Mon, 26 Feb 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/deadlines/ - <p><strong>TL;DR Always set a deadline</strong>. This post explains why we recommend being deliberate about setting deadlines, with useful code snippets to show you how.</p> - - - - 2018-01-19 gRPC-Go Engineering Practices - https://cjyabraham.github.io/blog/2018-01-22-grpc-go-engineering-practices/ - Mon, 22 Jan 2018 00:00:00 +0000 - - https://cjyabraham.github.io/blog/2018-01-22-grpc-go-engineering-practices/ - <p>It&rsquo;s the start of the new year, and almost the end of my first full year on the -gRPC-Go project, so I&rsquo;d like to take this opportunity to provide an update on -the state of gRPC-Go development and give some visibility into how we manage the -project. For me, personally, this is the first open source project to which -I&rsquo;ve meaningfully contributed, so this year has been a learning experience for -me. Over this year, the team has made constant improvements to our work habits -and communication. I still see room for improvement, but I believe we are in a -considerably better place than we were a year ago.</p> - - - - The gRPC Meetup Kit - https://cjyabraham.github.io/blog/meetup-kit/ - Thu, 14 Sep 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/meetup-kit/ - -<p>If you have ever wanted to run an event around <a href="http://grpc.io">gRPC</a>, but didn&rsquo;t know where to start, or wasn&rsquo;t sure what content is available - we have released the <a href="https://github.com/grpc-ecosystem/meetup-kit">gRPC Meetup Kit</a>!</p> - - - - - - 2017-08-22 gRPC-Go performance Improvements - https://cjyabraham.github.io/blog/2017-08-22-grpc-go-perf-improvements/ - Tue, 22 Aug 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/2017-08-22-grpc-go-perf-improvements/ - <p><p> -<span style="margin-bottom:5%">For past few months we&rsquo;ve been working on improving gRPC-Go performance. This includes improving network utilization, optimizing CPU usage and memory allocations. Most of our recent effort has been focused around revamping gRPC-Go flow control. After several optimizations and new features we&rsquo;ve been able to improve quite significantly, especially on high-latency networks. We expect users that are working with high-latency networks and large messages to see an order of magnitude performance gain. -Benchmark results at the end.</p> - -<p>This blog summarizes the work we have done so far (in chronological order) to improve performance and lays out our near-future plans.</style> -</p><br></p> - - - - 2017-08-17 Community Meeting Update - https://cjyabraham.github.io/blog/2017-08-17-community-meeting-update/ - Thu, 17 Aug 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/2017-08-17-community-meeting-update/ - <p><strong>Next Community Meeting:</strong> Thursday, August 31, 2017 11am Pacific Time (US and Canada)</p> - - - - Announcing out of the box support for gRPC in the Flatbuffers serialization library. - https://cjyabraham.github.io/blog/flatbuffers/ - Thu, 17 Aug 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/flatbuffers/ - <p>The recent release of Flatbuffers <a href="https://github.com/google/flatbuffers/releases">version 1.7</a> introduced truly zero-copy support for gRPC out of the box.</p> - -<p><a href="https://google.github.io/flatbuffers/">Flatbuffers</a> is a serialization library that allows you to access serialized data without first unpacking it or allocating any -additional data structures. It was originally designed for games and other resource constrained applications, but is now finding more general use, both by teams within Google and in other companies such as Netflix and Facebook.</p> - - - - gRPC Load Balancing - https://cjyabraham.github.io/blog/loadbalancing/ - Thu, 15 Jun 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/loadbalancing/ - <p>This post describes various load balancing scenarios seen when deploying gRPC. If you use <a href="https://cjyabraham.github.io/">gRPC</a> with multiple backends, this document is for you.</p> - -<p>A large scale gRPC deployment typically has a number of identical back-end instances, and a number of clients. Each server has a certain capacity. Load balancing is used for distributing the load from clients optimally across available servers.</p> - - - - gRPC in Helm - https://cjyabraham.github.io/blog/helmgrpc/ - Mon, 15 May 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/helmgrpc/ - <p><em>Our guest post today comes from Brian Hardock, a software engineer from Deis working on the <a href="https://helm.sh/">Helm</a> project.</em></p> - -<p>Helm is the package manager for Kubernetes. Helm provides its users with a customizable mechanism for -managing distributed applications and controlling their deployment.</p> - -<p>I have the good fortune to be a member of the phenomenal open-source Kubernetes Helm community serving as -a core contributor. My first day working with the Helm team was spent prototyping the architecture for -the next generation of Helm. By the end of that day, we had procured the preliminary RPC protocol data model -used to enable communication between Helm and its in-cluster server component, Tiller.</p> - - - - Migration to Google Cloud Platform — gRPC & grpc-gateway - https://cjyabraham.github.io/blog/yygrpc/ - Wed, 12 Apr 2017 00:00:00 +0000 - - https://cjyabraham.github.io/blog/yygrpc/ - <p>Our guest post today comes from <a href="https://www.linkedin.com/in/miguel-mendez-008231/">Miguel Mendez</a> of Yik Yak.</p> - -<p><em>This post was originally a part of the <a href="https://medium.com/yik-yak-eng">Yik Yak Engineering Blog</a> which focused on sharing the lessons learned as we evolved Yik Yak from early-stage startup code running in Amazon Web Services to an eventual incremental rewrite, re-architecture, and live-migration to Google Cloud Platform.</em></p> - -<p>In our previous blog <a href="https://medium.com/yik-yak-eng/migration-to-google-cloud-platform-overview-9b5e5c17c368">post</a> we gave an overview of our migration to Google Cloud Platform from Amazon Web Services. In this post we will drill down into the role that <a href="https://cjyabraham.github.io/">gRPC</a> and <a href="https://github.com/grpc-ecosystem/grpc-gateway">grpc-gateway</a> played in that migration and share some lessons which we picked up along the way.</p> - - - - Building gRPC services with bazel and rules_protobuf - https://cjyabraham.github.io/blog/bazel_rules_protobuf/ - Thu, 13 Oct 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/bazel_rules_protobuf/ - <p><a href="https://cjyabraham.github.io/">gRPC</a> makes it easier to build high-performance -microservices by providing generated service entrypoints in a variety -of different languages. <a href="https://bazel.io">Bazel</a> complements these -efforts with a capable and fast polyglot build environment.</p> - -<p><a href="https://github.com/pubref/rules_protobuf">rules_protobuf</a> extends -bazel and makes it easier develop gRPC services.</p> - - - - gRPC at VSCO - https://cjyabraham.github.io/blog/vscogrpc/ - Tue, 06 Sep 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/vscogrpc/ - <p>Our guest post today comes from Robert Sayre and Melinda Lu of VSCO.</p> - -<p>Founded in 2011, <a href="https://vsco.co">VSCO</a> is a community for expression—empowering people to create, discover and connect through images and words. VSCO is in the process of migrating their stack to gRPC.</p> - - - - Why we have decided to move our APIs to gRPC - https://cjyabraham.github.io/blog/vendastagrpc/ - Mon, 29 Aug 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/vendastagrpc/ - Our guest post today comes from Dale Hopkins, CTO of Vendasta. -Vendasta started out 8 years ago as a point solution provider of products for small business. From the beginning we partnered with media companies and agencies who have armies of salespeople and existing relationships with those businesses to sell our software. It is estimated that over 30 million small businesses exist in the United States alone, so scalability of our SaaS solution was considered one of our top concerns from the beginning and it was the reason we started with Google App Engine and Datastore. - - - - gRPC Project is now 1.0 and ready for production deployments - https://cjyabraham.github.io/blog/gablogpost/ - Tue, 23 Aug 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/gablogpost/ - Today, the gRPC project has reached a significant milestone with its 1.0 release. Languages moving to 1.0 include C++, Java, Go, Node, Ruby, Python and C# across Linux, Windows, and Mac. Objective-C and Android Java support on iOS and Android is also moving to 1.0. The 1.0 release means that the core protocol and API surface are now stable with measured performance, stress tested and developers can rely on these APIs and deploy in production, they will follow semantic versioning from here. - - - - gRPC with REST and Open APIs - https://cjyabraham.github.io/blog/coreos/ - Mon, 09 May 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/coreos/ - <p>Our guest post today comes from Brandon Phillips of <a href="https://coreos.com/">CoreOS</a>. CoreOS builds open source projects and products for Linux Containers. Their flagship product for consensus and discovery <a href="https://coreos.com/etcd/">etcd</a> and their container engine <a href="https://coreos.com/rkt/">rkt</a> are early adopters of gRPC.</p> - -<p>One of the key reasons CoreOS chose gRPC is because it uses HTTP/2, enabling applications to present both a HTTP 1.1 REST/JSON API and an efficient gRPC interface on a single TCP port (available for Go). This provides developers with compatibility with the REST web ecosystem, while advancing a new, high-efficiency RPC protocol. With the recent release of Go 1.6, Go ships with a stable <code>net/http2</code> package by default.</p> - - - - gRPC - now with easy installation. - https://cjyabraham.github.io/blog/installation/ - Mon, 04 Apr 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/installation/ - <p>Today we are happy to provide an update that significantly simplifies the getting started experience for gRPC.</p> - -<ul> -<li><p>For most languages, <strong>the gRPC runtime can now be installed in a single step via native package managers</strong> such as <code>npm</code> for Node.js, <code>gem</code> for Ruby and <code>pip</code> for Python. Even though our Node, Ruby and Python runtimes are wrapped on gRPC&rsquo;s C core, users now don&rsquo;t need to explicitly pre-install the C core library as a package in most Linux distributions. We autofetch it for you :-).</p></li> - -<li><p><strong>For Java, we have simplified the steps needed to add gRPC support to your build tools</strong> by providing plugins for Maven and Gradle. These let you easily depend on the core runtime to deploy or ship generated libraries into production environments.</p></li> - -<li><p>You can also use our Dockerfiles to use these updated packages - deploying microservices built on gRPC should now be a very simple experience.</p></li> -</ul> - - - - Google Cloud PubSub - with the power of gRPC! - https://cjyabraham.github.io/blog/pubsub/ - Thu, 24 Mar 2016 00:00:00 +0000 - - https://cjyabraham.github.io/blog/pubsub/ - <p><a href="https://cloud.google.com/pubsub/">Google Cloud PubSub</a> is Google&rsquo;s scalable real-time messaging service that lets users send and receive messages between independent applications. It&rsquo;s an important part of Google Cloud Platform&rsquo;s big data offering, and is used by customers worldwide to build their own robust, global services. However, until now, the only way to use the Cloud PubSub API was via JSON over HTTP. That&rsquo;s all changed with the release of <a href="https://cloud.google.com/blog/big-data/2016/03/announcing-grpc-alpha-for-google-cloud-pubsub">PubSub gRPC alpha</a>. Now <strong>users can access PubSub via gRPC</strong> and benefit from all the advantages it brings.</p> - - - - gRPC releases Beta, opening door for use in production environments. - https://cjyabraham.github.io/blog/beta_release/ - Mon, 26 Oct 2015 00:00:00 +0000 - - https://cjyabraham.github.io/blog/beta_release/ - -<p> - The gRPC team is excited to announce the immediate availability of gRPC Beta. This release marks an important point in API stability and going forward most API changes are expected to be additive in nature. This milestone opens the door for gRPC use in production environments. -</p> - - - - - - gRPC Motivation and Design Principles. - https://cjyabraham.github.io/blog/principles/ - Tue, 08 Sep 2015 00:00:00 +0000 - - https://cjyabraham.github.io/blog/principles/ - -<h2>Motivation</h2> - -<p>Google has been using a single general-purpose RPC infrastructure called Stubby to connect the large number of microservices running within and across our data centers for over a decade. Our internal systems have long embraced the microservice architecture gaining popularity today. Having a uniform, cross-platform RPC infrastructure has allowed for the rollout of fleet-wide improvements in efficiency, security, reliability and behavioral analysis critical to supporting the incredible growth seen in that period. -</p> - - - - - - \ No newline at end of file diff --git a/public/blog/installation/index.html b/public/blog/installation/index.html deleted file mode 100644 index 3213705..0000000 --- a/public/blog/installation/index.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - gRPC - now with easy installation. – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC - now with easy installation.

-
Posted on Monday, April 04, 2016 - - - - -
-

-

Today we are happy to provide an update that significantly simplifies the getting started experience for gRPC.

- - - -

The installation story is not yet complete: we are now focused on improving your development experience by packaging our protocol buffer plugins in the same way as the gRPC runtime. This will simplify code generation and setting up your development environment.

- -

Want to try it?

- -

Here’s how to install the gRPC runtime today in all our supported languages:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LanguagePlatformCommand
Node.jsLinux, Mac, Windowsnpm install grpc
PythonLinux, Mac, Windowspip install grpcio
RubyLinux, Mac, Windowsgem install grpc
PHPLinux, Mac, Windowspecl install grpc-beta
GoLinux, Mac, Windowsgo get google.golang.org/grpc
Objective-CMacRuntime source fetched automatically from GitHub by Cocoapods
C#WindowsInstall gRPC NuGet package from your IDE (Visual Studio, Monodevelop, Xamarin Studio)
JavaLinux, Mac, WindowsUse our Maven and Gradle plugins that provide gRPC with statically linked boringssl
C++Linux, Mac, WindowsCurrently requires manual build and install
- -

You can find out more about installation in our Getting Started guide and GitHub repositories. Do send us your feedback on our mailing list or file issues on our issue tracker if you run into any problems.

-

- - -
- - - - - - - - - - diff --git a/public/blog/kotlin-gradle-projects/index.html b/public/blog/kotlin-gradle-projects/index.html deleted file mode 100644 index 773d3df..0000000 --- a/public/blog/kotlin-gradle-projects/index.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - - - - - - gRPC ❤ Kotlin – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC ❤ Kotlin

-
Posted on Tuesday, June 19, 2018 - by - - Spencer Fang - -
-

-

Did you know that gRPC Java now has out of box support for Kotlin projects built with Gradle? Kotlin is a modern, statically typed language developed by JetBrains that targets the JVM and Android. It is generally easy for Kotlin programs to interoperate with existing Java libraries. To improve this experience further, we have added support to the protobuf-gradle-plugin so that the generated Java libraries are automatically picked up by Kotlin. You can now add the protobuf-gradle-plugin to your Kotlin project, and use gRPC just like you would with a typical Java project.

- -

The following examples show you how to configure a project for a JVM application and an Android application using Kotlin.

- -

Kotlin gRPC client and server

- -

The full example can be found here.

- -

Configuring gRPC for a Kotlin project is the same as configuring it for a Java project.

- -

Below is a snippet of the example project’s build.gradle highlighting some Kotlin related sections:

-
apply plugin: 'kotlin'
-apply plugin: 'com.google.protobuf'
-
-// Generate IntelliJ IDEA's .idea & .iml project files.
-// protobuf-gradle-plugin automatically registers *.proto and the gen output files
-// to IntelliJ as sources.
-// For best results, install the Protobuf and Kotlin plugins for IntelliJ.
-apply plugin: 'idea'
-
-buildscript {
-  ext.kotlin_version = '1.2.21'
-
-  repositories {
-    mavenCentral()
-  }
-  dependencies {
-    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
-    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
-  }
-}
-
-dependencies {
-  compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-  // The rest of the projects dep are added below, refer to example URL
-}
-
-// The standard protobuf block, same as normal gRPC Java projects
-protobuf {
-  protoc { artifact = 'com.google.protobuf:protoc:3.5.1-1' }
-    plugins {
-      grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
-    }
-    generateProtoTasks {
-      all()*.plugins { grpc {} }
-    }
-}
-

Now Kotlin source files can use the proto generated messages and gRPC stubs. By default, Kotlin sources should be placed in src/main/kotlin and src/test/kotlin. If needed, run ./gradlew generateProto generateTestProto and refresh IntelliJ for the generated sources to appear in the IDE. Finally, run ./gradlew installDist to build the project, and use ./build/install/examples/bin/hello-world-client or ./build/install/examples/bin/hello-world-server to run the example.

- -

You can read more about configuring Kotlin here.

- -

Kotlin Android gRPC application

- -

The full example can be found here.

- -

Configuring gRPC for a Kotlin Android project is the same as configuring it for a normal Android project.

- -

In the top level build.gradle file:

-
buildscript {
-  ext.kotlin_version = '1.2.21'
-
-  repositories {
-    google()
-    jcenter()
-  }
-  dependencies {
-    classpath 'com.android.tools.build:gradle:3.0.1'
-    classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5"
-    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
-  }
-}
-
-allprojects {
-  repositories {
-    google()
-    jcenter()
-  }
-}
-

And in the app module’s build.gradle file:

-
apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-android-extensions'
-apply plugin: 'com.google.protobuf'
-
-repositories {
-  mavenCentral()
-}
-
-dependencies {
-  compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-  // refer to full example for remaining deps
-}
-
-protobuf {
-  // The normal gRPC configuration for Android goes here
-}
-
-android {
-  // Android Studio 3.1 does not automatically pick up 'src/main/kotlin' as source files
-  sourceSets {
-    main.java.srcDirs += 'src/main/kotlin'
-  }
-}
-

Just like the non-Android project, run ./gradlew generateProto generateProto to run the proto code generator and ./gradlew build to build the project.

- -

Finally, test out the Android app by opening the project in Android Studio and selecting Run > Run 'app'.

- -

Kotlin Android app example

- -

We are excited about improving the gRPC experience for Kotlin developers. Please add enhancement ideas or bugs to the protobuf-gradle-plugin issue tracker or the grpc-java issue tracker.

-

- - -
- - - - - - - - - - diff --git a/public/blog/loadbalancing/index.html b/public/blog/loadbalancing/index.html deleted file mode 100644 index dd975a6..0000000 --- a/public/blog/loadbalancing/index.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - - - - - - - - - gRPC Load Balancing – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC Load Balancing

-
Posted on Thursday, June 15, 2017 - by - - makdharma - -
-

-

This post describes various load balancing scenarios seen when deploying gRPC. If you use gRPC with multiple backends, this document is for you.

- -

A large scale gRPC deployment typically has a number of identical back-end instances, and a number of clients. Each server has a certain capacity. Load balancing is used for distributing the load from clients optimally across available servers.

- -

Why gRPC?

- -

gRPC is a modern RPC protocol implemented on top of HTTP/2. HTTP/2 is a Layer 7 (Application layer) protocol, that runs on top of a TCP (Layer 4 - Transport layer) protocol, which runs on top of IP (Layer 3 - Network layer) protocol. gRPC has many advantages over traditional HTTP/REST/JSON mechanism such as

- -
    -
  1. Binary protocol (HTTP/2),

  2. - -
  3. Multiplexing many requests on one connection (HTTP/2)

  4. - -
  5. Header compression (HTTP/2)

  6. - -
  7. Strongly typed service and message definition (Protobuf)

  8. - -
  9. Idiomatic client/server library implementations in many languages

  10. -
- -

In addition, gRPC integrates seamlessly with ecosystem components like service discovery, name resolver, load balancer, tracing and monitoring, among others.

- -

Load balancing options

- -

Proxy or Client side?

- -

Note: Proxy load balancing is also known as server-side load balancing in some literature.

- -

Deciding between proxy versus client-side load balancing is a primary architectural choice. In Proxy load balancing, the client issues RPCs to the a Load Balancer (LB) proxy. The LB distributes the RPC call to one of the available backend servers that implement the actual logic for serving the call. The LB keeps track of load on each backend and implements algorithms for distributing load fairly. The clients themselves do not know about the backend servers. Clients can be untrusted. This architecture is typically used for user facing services where clients from open internet can connect to servers in a data center, as shown in the picture below. In this scenario, clients make requests to LB (#1). The LB passes on the request to one of the backends (#2), and the backends report load to LB (#3).

- -

image alt text

- -

In Client side load balancing, the client is aware of multiple backend servers and chooses one to use for each RPC. The client gets load reports from backend servers and the client implements the load balancing algorithms. In simpler configurations server load is not considered and client can just round-robin between available servers. This is shown in the picture below. As you can see, the client makes request to a specific backend (#1). The backends respond with load information (#2), typically on the same connection on which client RPC is executed. The client then updates its internal state.

- -

image alt text

- -

The following table outlines the pros and cons of each model.

- - - - - - - - - - - - - - - - - -
ProxyClient Side
Pros -le client -* No client-side awareness of backend -* Works with untrusted clients - - -* High performance because elimination of extra hop -
Cons - -* LB is in the data path -* Higher latency -* LB throughput may limit scalability - - -* Complex client -* Client keeps track of server load and health -* Client implements load balancing algorithm -* Per-language implementation and maintenance burden -* Client needs to be trusted, or the trust boundary needs to be handled by a lookaside LB. - -
- -

Proxy Load Balancer options

- -

Proxy load balancing can be L3/L4 (transport level) or L7 (application level). In transport level load balancing, the server terminates the TCP connection and opens another connection to the backend of choice. The application data (HTTP/2 and gRPC frames) are simply copied between the client connection to the backend connection. L3/L4 LB by design does very little processing, adds less latency compared with L7 LB, and is cheaper because it consumes fewer resources.

- -

In L7 (application level) load balancing, the LB terminates and parses the HTTP/2 protocol. The LB can inspect each request and assign a backend based on the request contents. For example, a session cookie sent as part of HTTP header can be used to associate with a specific backend, so all requests for that session are served by the same backend. Once the LB has chosen an appropriate backend, it creates a new HTTP/2 connection to that backend. It then forwards the HTTP/2 streams received from the client to the backend(s) of choice. With HTTP/2, LB can distribute the streams from one client among multiple backends.

- -

L3/L4 (Transport) vs L7 (Application)

- - - - - - - - - - - - - - - - - - - - - - -
- Use case - - Recommendation -
RPC load varies a lot among connectionsUse Application level LB
Storage or compute affinity is importantUse Application level LB and use cookies or similar for routing requests to correct backend
Minimizing resource utilization in proxy is more important than featuresUse L3/L4 LB
Latency is paramountUse L3/L4 LB
- -

Client side LB options

- -

Thick client

- -

A thick client approach means the load balancing smarts are implemented in the client. The client is responsible for keeping track of available servers, their workload, and the algorithms used for choosing servers. The client typically integrates libraries that communicate with other infrastructures such as service discovery, name resolution, quota management, etc.

- -

Lookaside Load Balancing

- -

Note: A lookaside load balancer is also known as an external load balancer or one-arm load balancer

- -

With lookaside load balancing, the load balancing smarts are implemented in a special LB server. Clients query the lookaside LB and the LB responds with best server(s) to use. The heavy lifting of keeping server state and implementation of LB algorithm is consolidated in the lookaside LB. Note that client might choose to implement simple algorithms on top of the sophisticated ones implemented in the LB. gRPC defines a protocol for communication between client and LB using this model. See Load Balancing in gRPC doc for details.

- -

The picture below illustrates this approach. The client gets at least one address from lookaside LB (#1). Then the client uses this address to make a RPC (#2), and server sends load report to the LB (#3). The lookaside LB communicates with other infrastructure such as name resolution, service discovery, and so on (#4).

- -

image alt text

- -

Recommendations and best practices

- -

Depending upon the particular deployment and constraints, we suggest the following.

- - - - - - - - - - - - - - - - - - - - - - -
SetupRecommendation
- -* Very high traffic between clients and servers -* Clients can be trusted - - -* Thick client-side load balancing -* Client side LB with ZooKeeper/Etcd/Consul/Eureka. [ZooKeeper Example](https://github.com/makdharma/grpc-zookeeper-lb). - -
- -* Traditional setup - Many clients connecting to services behind a proxy -* Need trust boundary between servers and clients - - -* Proxy Load Balancing -* L3/L4 LB with GCLB (if using GCP) -* L3/L4 LB with haproxy - [Config file](https://gist.github.com/thpham/114d20de8472b2cef966) -* Nginx coming soon -* If need session stickiness - L7 LB with Envoy as proxy -
- -* Microservices - N clients, M servers in the data center -* Very high performance requirements (low latency, high traffic) -* Client can be untrusted - - -* Look-aside Load Balancing -* Client-side LB using [gRPC-LB protocol](https://github.com/grpc/grpc/blob/master/doc/load-balancing.md). Roll your own implementation (Q2’17), hosted gRPC-LB in the works. -
- -* Existing Service-mesh like setup using Linkerd or Istio - - -* Service Mesh -* Use built-in LB with [Istio](https://istio.io/), or [Envoy](https://github.com/lyft/envoy). -
-

- - -
- - - - - - - - - - diff --git a/public/blog/meetup-kit/index.html b/public/blog/meetup-kit/index.html deleted file mode 100644 index da159f1..0000000 --- a/public/blog/meetup-kit/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - The gRPC Meetup Kit – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

The gRPC Meetup Kit

-
Posted on Thursday, September 14, 2017 - - - - -
-

-

The meetup kit includes a 15 minute presentation on the basic concepts of gRPC, with accompanying slides and video for either reference or playback, as well as a 45 minute codelab that takes you through the basics of gRPC in Node.js and Go. At the end of the codelab participants will have a solid understanding of the fundamentals of gRPC.

-

If you are thinking about running a gRPC event, make sure to contact us to receive gRPC stickers and/or organise office hours over Hangouts with the gRPC team!

- -

- - -
- - - - - - - - - - diff --git a/public/blog/optimizing-grpc-part-1/index.html b/public/blog/optimizing-grpc-part-1/index.html deleted file mode 100644 index b7e31ba..0000000 --- a/public/blog/optimizing-grpc-part-1/index.html +++ /dev/null @@ -1,500 +0,0 @@ - - - - - - - - - - - - So You Want to Optimize gRPC - Part 1 – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

So You Want to Optimize gRPC - Part 1

-
Posted on Tuesday, March 06, 2018 - by - - Carl Mastrangelo - -
-

-

A common question with gRPC is how to make it fast. The gRPC library offers users access to high -performance RPCs, but it isn’t always clear how to achieve this. Because this question is common -enough I thought I would try to show my thought process when tuning programs.

- -

Setup

- -

Consider a basic key-value service that is used by multiple other programs. The service needs to -be safe for concurrent access in case multiple updates happen at the same time. It needs to be -able to scale up to use the available hardware. Lastly, it needs to be fast. gRPC is a perfect -fit for this type of service; let’s look at the best way to implement it.

- -

For this blog post, I have written an example -client and server using gRPC Java. The program is -split into three main classes, and a protobuf file describing the API:

- - - -

Protocol buffers(protos) aren’t required to use -gRPC, they are a very convenient way to define service interfaces and generate client and server -code. The generated code acts as glue code between the application logic and the core gRPC -library. We refer to the code called by a gRPC client the stub.

- -

Starting Point

- -

Client

- -

Now that we know what the program should do, we can start looking at how the program performs. -As mentioned above, the client makes random RPCs. For example, here is the code that makes the -creation -request:

-
  private void doCreate(KeyValueServiceBlockingStub stub) {
-    ByteString key = createRandomKey();
-    try {
-      CreateResponse res = stub.create(
-          CreateRequest.newBuilder()
-              .setKey(key)
-              .setValue(randomBytes(MEAN_VALUE_SIZE))
-              .build());
-      if (!res.equals(CreateResponse.getDefaultInstance())) {
-        throw new RuntimeException("Invalid response");
-      }
-    } catch (StatusRuntimeException e) {
-      if (e.getStatus().getCode() == Code.ALREADY_EXISTS) {
-        knownKeys.remove(key);
-        logger.log(Level.INFO, "Key already existed", e);
-      } else {
-        throw e;
-      }
-    }
-  }
-

A random key is created, along with a random value. The request is sent to the server, and the -client waits for the response. When the response is returned, the code checks that it is as -expected, and if not, throws an exception. While the keys are chosen randomly, they need to be -unique, so we need to make sure that each key isn’t already in use. To address this, the code -keeps track of keys it has created, so as not to create the same key twice. However, it’s -possible that another client already created a particular key, so we log it and move on. -Otherwise, an exception is thrown.

- -

We use the blocking gRPC API here, which issues a requests and waits for a response. -This is the simplest gRPC stub, but it blocks the thread while running. This means that at most -one RPC can be in progress at a time from the client’s point of view.

- -

Server

- -

On the server side, the request is received by the -service handler:

-
  private final Map<ByteBuffer, ByteBuffer> store = new HashMap<>();
-
-  @Override
-  public synchronized void create(
-      CreateRequest request, StreamObserver<CreateResponse> responseObserver) {
-    ByteBuffer key = request.getKey().asReadOnlyByteBuffer();
-    ByteBuffer value = request.getValue().asReadOnlyByteBuffer();
-    simulateWork(WRITE_DELAY_MILLIS);
-    if (store.putIfAbsent(key, value) == null) {
-      responseObserver.onNext(CreateResponse.getDefaultInstance());
-      responseObserver.onCompleted();
-      return;
-    }
-    responseObserver.onError(Status.ALREADY_EXISTS.asRuntimeException());
-  }
-

The service extracts the key and value as ByteBuffers from the request. It acquires the lock -on the service itself to make sure concurrent requests don’t corrupt the storage. After -simulating the disk access of a write, it stores it in the Map of keys to values.

- -

Unlike the client code, the service handler is non-blocking, meaning it doesn’t return a -value like a function call would. Instead, it invokes onNext() on the responseObserver to -send the response back to the client. Note that this call is also non-blocking, meaning that -the message may not yet have been sent. To indicate we are done with the message, onCompleted() -is called.

- -

Performance

- -

Since the code is safe and correct, let’s see how it performs. For my measurement I’m using my -Ubuntu system with a 12 core processor and 32 GB of memory. Let’s build and run the code:

-
$ ./gradlew installDist
-$ time ./build/install/kvstore/bin/kvstore
-Feb 26, 2018 1:10:07 PM io.grpc.examples.KvRunner runClient
-INFO: Starting
-Feb 26, 2018 1:11:07 PM io.grpc.examples.KvRunner runClient
-INFO: Did 16.55 RPCs/s
-
-real	1m0.927s
-user	0m10.688s
-sys	0m1.456s
-

Yikes! For such a powerful machine, it can only do about 16 RPCs per second. It hardly used any -of our CPU, and we don’t know how much memory it was using. We need to figure out why it’s so -slow.

- -

Optimization

- -

Analysis

- -

Let’s understand what the program is doing before we make any changes. When optimizing, we need -to know where the code is spending its time in order to know what we can optimize. At this early -stage, we don’t need profiling tools yet, we can just reason about the program.

- -

The client is started and serially issues RPCs for about a minute. Each iteration, it randomly -decides -what operation to do:

-
  void doClientWork(AtomicBoolean done) {
-    Random random = new Random();
-    KeyValueServiceBlockingStub stub = KeyValueServiceGrpc.newBlockingStub(channel);
-
-    while (!done.get()) {
-      // Pick a random CRUD action to take.
-      int command = random.nextInt(4);
-      if (command == 0) {
-        doCreate(stub);
-        continue;
-      }
-      /* ... */
-      rpcCount++;
-    }
-  }
-

This means that at most one RPC can be active at any time. Each RPC has to wait for the -previous one to complete. And how long does each RPC take to complete? From reading the server -code, most of the operations are doing a write which takes about 50 milliseconds. At top -efficiency, the most operations this code can do per second is about 20:

- -

20 queries = 1000ms / (50 ms / query)

- -

Our code can do about 16 queries in a second, so that seems about right. We can spot check this -assumption by looking at the output of the time command used to run the code. The server goes -to sleep when running queries in the -simulateWork -method. This implies that the program should be mostly idle while waiting for the RPCs to -complete.

- -

We can confirm this is the case by looking at the real and user times of the command above. -They say that the amount of wall clock time was 1 minute, while the amount of cpu time -was 10 seconds. My powerful, multicore CPU was only busy 16% of the time. Thus, if we could -get the program to do more work during that time, it seems like we could get more RPCs complete.

- -

Hypothesis

- -

Now we can state clearly what we think is the problem, and propose a solution. One way to speed -up programs is to make sure the CPU is not idling. To do this, we issue work concurrently.

- -

In gRPC Java, there are three types of stubs: blocking, non-blocking, and listenable future. We -have already seen the blocking stub in the client, and the non-blocking stub in the server. The -listenable future API is a compromise between the two, offering both blocking and non-blocking -like behavior. As long as we don’t block a thread waiting for work to complete, we can start -new RPCs without waiting for the old ones to complete.

- -

Experiment

- -

To test our hypothesis, let’s modify the client code to use the listenable future API. This -means that we need to think more about concurrency in our code. For example, when keeping track -of known keys client-side, we need to safely read, modify, and write the keys. We also need to -make sure that in case of an error, we stop making new RPCs (proper error handling will be covered -in a future post). Lastly, we need to update the number of RPCs made concurrently, since the -update could happen in another thread.

- -

Making all these changes increases the complexity of the code. This is a trade off you will need -to consider when optimizing your code. In general, code simplicity is at odds with optimization. -Java is not known for being terse. That said, the code below is still readable, and program flow -is still roughly from top to bottom in the function. Here is the -doCreate() -method revised:

-
  private void doCreate(KeyValueServiceFutureStub stub, AtomicReference<Throwable> error) {
-    ByteString key = createRandomKey();
-    ListenableFuture<CreateResponse> res = stub.create(
-        CreateRequest.newBuilder()
-            .setKey(key)
-            .setValue(randomBytes(MEAN_VALUE_SIZE))
-            .build());
-    res.addListener(() -> rpcCount.incrementAndGet(), MoreExecutors.directExecutor());
-    Futures.addCallback(res, new FutureCallback<CreateResponse>() {
-      @Override
-      public void onSuccess(CreateResponse result) {
-        if (!result.equals(CreateResponse.getDefaultInstance())) {
-          error.compareAndSet(null, new RuntimeException("Invalid response"));
-        }
-        synchronized (knownKeys) {
-          knownKeys.add(key);
-        }
-      }
-
-      @Override
-      public void onFailure(Throwable t) {
-        Status status = Status.fromThrowable(t);
-        if (status.getCode() == Code.ALREADY_EXISTS) {
-          synchronized (knownKeys) {
-            knownKeys.remove(key);
-          }
-          logger.log(Level.INFO, "Key already existed", t);
-        } else {
-          error.compareAndSet(null, t);
-        }
-      }
-    });
-  }
-

The stub has been modified to be a KeyValueServiceFutureStub, which produces a Future when -called instead of the response itself. gRPC Java uses an extension of this called ListenableFuture, -which allows adding a callback when the future completes. For the sake of this program, we are -not as concerned with getting the response. Instead we care more if the RPC succeeded or not. -With that in mind, the code mainly checks for errors rather than processing the response.

- -

The first change made is how the number of RPCs is recorded. Instead of incrementing the counter -outside of the main loop, we increment it when the RPC completes.

- -

Next, we create a new object -for each RPC which handles both the success and failure cases. Because doCreate() will already -be completed by the time RPC callback is invoked, we need a way to propagate errors other than -by throwing. Instead, we try to update an reference atomically. The main loop will occasionally -check if an error has occurred and stop if there is a problem.

- -

Lastly, the code is careful to only add a key to knownKeys when the RPC is actually complete, -and only remove it when known to have failed. We synchronize on the variable to make sure two -threads don’t conflict. Note: although the access to knownKeys is threadsafe, there are still -race conditions. It is possible that one thread -could read from knownKeys, a second thread delete from knownKeys, and then the first thread -issue an RPC using the first key. Synchronizing on the keys only ensures that it is consistent, -not that it is correct. Fixing this properly is outside of the scope of this post, so instead we -just log the event and move on. You will see a few such log statements if you run this program.

- -

Running the Code

- -

If you start up this program and run it, you’ll notice that it doesn’t work:

-
WARNING: An exception was thrown by io.grpc.netty.NettyClientStream$Sink$1.operationComplete()
-java.lang.OutOfMemoryError: unable to create new native thread
-	at java.lang.Thread.start0(Native Method)
-	at java.lang.Thread.start(Thread.java:714)
-	...
-

What?! Why would I show you code that fails? The reason is that in real life making a change often -doesn’t work on the first try. In this case, the program ran out of memory. Odd things begin to -happen when a program runs out of memory. Often, the root cause is hard to find, and red herrings -abound. A confusing error message says

- -
-

unable to create new native thread

-
- -

even though we didn’t create any new threads in our code. Experience is very helpful in fixing -these problems rather than debugging. Since I have debugged many OOMs, I happen to know Java tells -us about the straw that broke the camel’s back. Our program started using way more memory, but the -final allocation that failed happened, by chance, to be in thread creation.

- -

So what happened? There was no pushback to starting new RPCs. In the blocking version, a new -RPC couldn’t start until the last one completed. While slow, it also prevented us from creating -tons of RPCs that we didn’t have memory for. We need to account for this in the listenable -future version.

- -

To solve this, we can apply a self-imposed limit on the number of active RPCs. Before starting a -new RPC, we will try to acquire a permit. If we get one, the RPC can start. If not, we will wait -until one is available. When an RPC completes (either in success or failure), we return the -permit. To accomplish -this, we will using a Semaphore:

-
  private final Semaphore limiter = new Semaphore(100);
-
-  private void doCreate(KeyValueServiceFutureStub stub, AtomicReference<Throwable> error)
-      throws InterruptedException {
-    limiter.acquire();
-    ByteString key = createRandomKey();
-    ListenableFuture<CreateResponse> res = stub.create(
-        CreateRequest.newBuilder()
-            .setKey(key)
-            .setValue(randomBytes(MEAN_VALUE_SIZE))
-            .build());
-    res.addListener(() ->  {
-      rpcCount.incrementAndGet();
-      limiter.release();
-    }, MoreExecutors.directExecutor());
-    /* ... */
-  }
-

Now the code runs successfully, and doesn’t run out of memory.

- -

Results

- -

Building and running the code again looks a lot better:

-
$ ./gradlew installDist
-$ time ./build/install/kvstore/bin/kvstore
-Feb 26, 2018 2:40:47 PM io.grpc.examples.KvRunner runClient
-INFO: Starting
-Feb 26, 2018 2:41:47 PM io.grpc.examples.KvRunner runClient
-INFO: Did 24.283 RPCs/s
-
-real	1m0.923s
-user	0m12.772s
-sys	0m1.572s
-

Our code does 46% more RPCs per second than previously. We can also see that we used about 20% -more CPU than previously. As we can see our hypothesis turned out to be correct and the fix -worked. All this happened without making any changes to the server. Also, we were able to -measure without using any special profilers or tracers.

- -

Do the numbers make sense? We expect to issue mutation (create, update, and delete) RPCs each -about with 14 probability. Reads are also issue 14 of the time, but don’t take as long. The -mean RPC time should be about the weighted average RPC time:

- -
  .25 * 50ms (create)
-  .25 * 10ms (retrieve)
-  .25 * 50ms (update)
- +.25 * 50ms (delete)
-------------
-        40ms
-
- -

At 40ms on average per RPC, we would expect the number of RPCs per second to be:

- -

25 queries = 1000ms / (40 ms / query)

- -

That’s approximately what we see with the new code. The server is still serially handling -requests, so it seems like we have more work to do in the future. But for now, our optimizations -seem to have worked.

- -

Conclusion

- -

There are a lot of opportunities to optimize your gRPC code. To take advantage of these, you -need to understand what your code is doing, and what your code is supposed to do. This post shows -the very basics of how to approach and think about optimization. Always make sure to measure -before and after your changes, and use these measurements to guide your optimizations.

- -

In Part 2, we will continue optimizing the server part of the code.

-

- - -
- - - - - - - - - - diff --git a/public/blog/optimizing-grpc-part-2/index.html b/public/blog/optimizing-grpc-part-2/index.html deleted file mode 100644 index db6de7b..0000000 --- a/public/blog/optimizing-grpc-part-2/index.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - - - - So You Want to Optimize gRPC - Part 2 – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

So You Want to Optimize gRPC - Part 2

-
Posted on Monday, April 16, 2018 - by - - Carl Mastrangelo - -
-

-

How fast is gRPC? Pretty fast if you understand how modern clients and servers are built. In -part 1, I showed how to get an easy 60% improvement. In this -post I show how to get a 10000% improvement.

- -

Setup

- -

As in part 1, we will start with an existing, Java based, -key-value service. The service will offer concurrent access for creating, reading, updating, -and deleting keys and values. All the code can be seen -here if you want to try -it out.

- -

Server Concurrency

- -

Let’s look at the KvService -class. This service handles the RPCs sent by the client, making sure that none of them -accidentally corrupt the state of storage. To ensure this, the service uses the synchronized -keyword to ensure only one RPC is active at a time:

-
  private final Map<ByteBuffer, ByteBuffer> store = new HashMap<>();
-
-  @Override
-  public synchronized void create(
-      CreateRequest request, StreamObserver<CreateResponse> responseObserver) {
-    ByteBuffer key = request.getKey().asReadOnlyByteBuffer();
-    ByteBuffer value = request.getValue().asReadOnlyByteBuffer();
-    simulateWork(WRITE_DELAY_MILLIS);
-    if (store.putIfAbsent(key, value) == null) {
-      responseObserver.onNext(CreateResponse.getDefaultInstance());
-      responseObserver.onCompleted();
-      return;
-    }
-    responseObserver.onError(Status.ALREADY_EXISTS.asRuntimeException());
-  }
-

While this code is thread safe, it comes at a high price: only one RPC can ever be active! We -need some way of allowing multiple operations to happen safely at the same time. Otherwise, -the program can’t take advantage of all the available processors.

- -

Breaking the Lock

- -

To solve this, we need to know a little more about the semantics of our RPCs. The more we know -about how the RPCs are supposed to work, the more optimizations we can make. For a key-value -service, we notice that operations to different keys don’t interfere with each other. When -we update key ‘foo’, it has no bearing on the value stored for key ‘bar’. But, our server is -written such that operations to any key must be synchronized with respect to each other. If we -could make operations to different keys happen concurrently, our server could handle a lot more -load.

- -

With the idea in place, we need to figure out how to modify the server. The -synchronized keyword causes Java to acquire a lock on this, which is the instance of -KvService. The lock is acquired when the create method is entered, and released on return. -The reason we need synchronization is to protect the store Map. Since it is implemented as a -HashMap, modifications to it change the internal -arrays. Because the internal state of the HashMap will be corrupted if not properly -synchronized, we can’t just remove the synchronization on the method.

- -

However, Java offers a solution here: ConcurrentHashMap. This class offers the ability to -safely access the contents of the map concurrently. For example, in our usage we want to check -if a key is present. If not present, we want to add it, else we want to return an error. The -putIfAbsent method atomically checks if a value is present, adds it if not, and tells us if -it succeeded.

- -

Concurrent maps provide stronger guarantees about the safety of putIfAbsent, so we can swap the -HashMap to a ConcurrentHashMap and remove synchronized:

-
  private final ConcurrentMap<ByteBuffer, ByteBuffer> store = new ConcurrentHashMap<>();
- 
-  @Override
-  public void create(
-      CreateRequest request, StreamObserver<CreateResponse> responseObserver) {
-    ByteBuffer key = request.getKey().asReadOnlyByteBuffer();
-    ByteBuffer value = request.getValue().asReadOnlyByteBuffer();
-    simulateWork(WRITE_DELAY_MILLIS);
-    if (store.putIfAbsent(key, value) == null) {
-      responseObserver.onNext(CreateResponse.getDefaultInstance());
-      responseObserver.onCompleted();
-      return;
-    }
-    responseObserver.onError(Status.ALREADY_EXISTS.asRuntimeException());
-  }
-

If at First You Don’t Succeed

- -

Updating create was pretty easy. Doing the same for retrieve and delete is easy too. -However, the update method is a little trickier. Let’s take a look at what it’s doing:

-
  @Override
-  public synchronized void update(
-      UpdateRequest request, StreamObserver<UpdateResponse> responseObserver) {
-    ByteBuffer key = request.getKey().asReadOnlyByteBuffer();
-    ByteBuffer newValue = request.getValue().asReadOnlyByteBuffer();
-    simulateWork(WRITE_DELAY_MILLIS);
-    ByteBuffer oldValue = store.get(key);
-    if (oldValue == null) {
-      responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
-      return;
-    }
-    store.replace(key, oldValue, newValue);
-    responseObserver.onNext(UpdateResponse.getDefaultInstance());
-    responseObserver.onCompleted();
-  }
-

Updating a key to a new value needs two interactions with the store:

- -
    -
  1. Check to see if the key exists at all.
  2. -
  3. Update the previous value to the new value.
  4. -
- -

Unfortunately ConcurrentMap doesn’t have a straightforward method to do this. Since we may not -be the only ones modifying the map, we need to handle the possibility that our assumptions -have changed. We read the old value out, but by the time we replace it, it may have been deleted.

- -

To reconcile this, let’s retry if replace fails. It returns true if the replace -was successful. (ConcurrentMap asserts that the operations will not corrupt the internal -structure, but doesn’t say that they will succeed!) We will use a do-while loop:

-
  @Override
-  public void update(
-      UpdateRequest request, StreamObserver<UpdateResponse> responseObserver) {
-    // ...
-    ByteBuffer oldValue;
-    do {
-      oldValue = store.get(key);
-      if (oldValue == null) {
-        responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
-        return;
-      }
-    } while (!store.replace(key, oldValue, newValue));
-    responseObserver.onNext(UpdateResponse.getDefaultInstance());
-    responseObserver.onCompleted();
-  }
-

The code wants to fail if it ever sees null, but never if there is a non-null previous value. One -thing to note is that if another RPC modifies the value between the store.get() call and the -store.replace() call, it will fail. This is a non-fatal error for us, so we will just try again. -Once it has successfully put the new value in, the service can respond back to the user.

- -

There is one other possibility that could happen: two RPCs could update the same value and -overwrite each other’s work. While this may be okay for some applications, it would not be -suitable for APIs that provide transactionality. It is out of scope for this post to show how to -fix this, but be aware it can happen.

- -

Measuring the Performance

- -

In the last post, we modified the client to be asynchronous and use the gRPC ListenableFuture API. -To avoid running out of memory, the client was modified to have at most 100 active RPCs at a -time. As we now see from the server code, performance was bottlenecked on acquiring locks. -Since we have removed those, we expect to see a 100x improvement. The same amount of work is done -per RPC, but a lot more are happening at the same time. Let’s see if our hypothesis holds:

- -

Before:

-
$ ./gradlew installDist
-$ time ./build/install/kvstore/bin/kvstore
-Apr 16, 2018 10:38:42 AM io.grpc.examples.KvRunner runClient
-INFO: Did 24.067 RPCs/s
-
-real	1m0.886s
-user	0m9.340s
-sys	0m1.660s
-

After:

-
Apr 16, 2018 10:36:48 AM io.grpc.examples.KvRunner runClient
-INFO: Did 2,449.8 RPCs/s
-
-real	1m0.968s
-user	0m52.184s
-sys	0m20.692s
-

Wow! From 24 RPCs per second to 2,400 RPCs per second. And we didn’t have to change our API or -our client. This is why understanding your code and API semantics is important. By exploiting the -properties of the key-value API, namely the independence of operations on different keys, the code -is now much faster.

- -

One noteworthy artifact of this code is the user timing in the results. Previously the user time -was only 9 seconds, meaning that the CPU was active only 9 of the 60 seconds the code was running. -Afterwards, the usage went up by more than 5x to 52 seconds. The reason is that more CPU cores are -active. The KvServer is simulating work by sleeping for a few milliseconds. In a real -application, it would be doing useful work and not have such a dramatic change. Rather than -scaling per the number of RPCs, it would scale per the number of cores. Thus, if your machine had -12 cores, you would expect to see a 12x improvement. Still not bad though!

- -

More Errors

- -

If you run this code yourself, you will see a lot more log spam in the form:

-
Apr 16, 2018 10:38:40 AM io.grpc.examples.KvClient$3 onFailure
-INFO: Key not found
-io.grpc.StatusRuntimeException: NOT_FOUND
-

The reason is that the new version of the code makes API level race conditions more apparent. -With 100 times as many RPCs happening, the chance of updates and deletes colliding with each other -is more likely. To solve this we will need to modify the API definition. Stay tuned for the next -post showing how to fix this.

- -

Conclusion

- -

There are a lot of opportunities to optimize your gRPC code. To take advantage of these, you -need to understand what your code is doing. This post shows how to convert a lock-based service into -a low-contention, lock-free service. Always make sure to measure before and after your changes.

- -

In Part 3, we will optimize the code even further. 2,400 RPC/s is just the beginning!

-

- - -
- - - - - - - - - - diff --git a/public/blog/page/1/index.html b/public/blog/page/1/index.html deleted file mode 100644 index fba230e..0000000 --- a/public/blog/page/1/index.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/blog/ \ No newline at end of file diff --git a/public/blog/page/2/index.html b/public/blog/page/2/index.html deleted file mode 100644 index afe258a..0000000 --- a/public/blog/page/2/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - - - - - - - Blogs – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- - -
-
- - -

Gracefully clean up in gRPC JUnit tests

-
June 26, 2018
-

-

It is best practice to always clean up gRPC resources such as client channels, servers, and previously attached Contexts whenever they are no longer needed.

- -

This is even true for JUnit tests, because otherwise leaked resources may not only linger in your machine forever, but also interfere with subsequent tests. A not-so-bad case is that subsequent tests can’t pass because of a leaked resource from the previous test. The worst case is that some subsequent tests pass that wouldn’t have passed at all if the previously passed test had not leaked a resource.

-

- -Read More -


- -

gRPC ❤ Kotlin

-
June 19, 2018
-

-

Did you know that gRPC Java now has out of box support for Kotlin projects built with Gradle? Kotlin is a modern, statically typed language developed by JetBrains that targets the JVM and Android. It is generally easy for Kotlin programs to interoperate with existing Java libraries. To improve this experience further, we have added support to the protobuf-gradle-plugin so that the generated Java libraries are automatically picked up by Kotlin. You can now add the protobuf-gradle-plugin to your Kotlin project, and use gRPC just like you would with a typical Java project.

-

- -Read More -


- -

So You Want to Optimize gRPC - Part 2

-
April 16, 2018
-

-

How fast is gRPC? Pretty fast if you understand how modern clients and servers are built. In -part 1, I showed how to get an easy 60% improvement. In this -post I show how to get a 10000% improvement.

-

- -Read More -


- -

So You Want to Optimize gRPC - Part 1

-
March 06, 2018
-

-

A common question with gRPC is how to make it fast. The gRPC library offers users access to high -performance RPCs, but it isn’t always clear how to achieve this. Because this question is common -enough I thought I would try to show my thought process when tuning programs.

-

- -Read More -


- -

gRPC and Deadlines

-
February 26, 2018
-

-

TL;DR Always set a deadline. This post explains why we recommend being deliberate about setting deadlines, with useful code snippets to show you how.

-

- -Read More -


- -

2018-01-19 gRPC-Go Engineering Practices

-
January 22, 2018
-

-

It’s the start of the new year, and almost the end of my first full year on the -gRPC-Go project, so I’d like to take this opportunity to provide an update on -the state of gRPC-Go development and give some visibility into how we manage the -project. For me, personally, this is the first open source project to which -I’ve meaningfully contributed, so this year has been a learning experience for -me. Over this year, the team has made constant improvements to our work habits -and communication. I still see room for improvement, but I believe we are in a -considerably better place than we were a year ago.

-

- -Read More -


- -

The gRPC Meetup Kit

-
September 14, 2017
-

- -

If you have ever wanted to run an event around gRPC, but didn’t know where to start, or wasn’t sure what content is available - we have released the gRPC Meetup Kit!

- - -

- -Read More -


- -

2017-08-22 gRPC-Go performance Improvements

-
August 22, 2017
-

-

-For past few months we’ve been working on improving gRPC-Go performance. This includes improving network utilization, optimizing CPU usage and memory allocations. Most of our recent effort has been focused around revamping gRPC-Go flow control. After several optimizations and new features we’ve been able to improve quite significantly, especially on high-latency networks. We expect users that are working with high-latency networks and large messages to see an order of magnitude performance gain. -Benchmark results at the end.

- -

This blog summarizes the work we have done so far (in chronological order) to improve performance and lays out our near-future plans. -


-

- -Read More -


- -

2017-08-17 Community Meeting Update

-
August 17, 2017
-

-

Next Community Meeting: Thursday, August 31, 2017 11am Pacific Time (US and Canada)

-

- -Read More -


- -

Announcing out of the box support for gRPC in the Flatbuffers serialization library.

-
August 17, 2017
-

-

The recent release of Flatbuffers version 1.7 introduced truly zero-copy support for gRPC out of the box.

- -

Flatbuffers is a serialization library that allows you to access serialized data without first unpacking it or allocating any -additional data structures. It was originally designed for games and other resource constrained applications, but is now finding more general use, both by teams within Google and in other companies such as Netflix and Facebook.

-

- -Read More -


- - - - - -
- - - -
- -
All blog posts
- - Dear gRPC

- - The state of gRPC in the browser

- - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

- - Visualizing gRPC Language Stacks

- - gRPC-Web is Generally Available

- - A short introduction to Channelz

- - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

- - gRPC + JSON

- - Take the gRPC Survey!

- - HTTP/2 Smarter At Scale

- - Gracefully clean up in gRPC JUnit tests

- - gRPC ❤ Kotlin

- - So You Want to Optimize gRPC - Part 2

- - So You Want to Optimize gRPC - Part 1

- - gRPC and Deadlines

- - 2018-01-19 gRPC-Go Engineering Practices

- - The gRPC Meetup Kit

- - 2017-08-22 gRPC-Go performance Improvements

- - 2017-08-17 Community Meeting Update

- - Announcing out of the box support for gRPC in the Flatbuffers serialization library.

- - gRPC Load Balancing

- - gRPC in Helm

- - Migration to Google Cloud Platform — gRPC & grpc-gateway

- - Building gRPC services with bazel and rules_protobuf

- - gRPC at VSCO

- - Why we have decided to move our APIs to gRPC

- - gRPC Project is now 1.0 and ready for production deployments

- - gRPC with REST and Open APIs

- - gRPC - now with easy installation.

- - Google Cloud PubSub - with the power of gRPC!

- - gRPC releases Beta, opening door for use in production environments.

- - gRPC Motivation and Design Principles.

- - -
- - - -
- - - - - - - - - - - diff --git a/public/blog/page/3/index.html b/public/blog/page/3/index.html deleted file mode 100644 index e19e9b9..0000000 --- a/public/blog/page/3/index.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - - - - - - - - Blogs – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- - -
-
- - -

gRPC Load Balancing

-
June 15, 2017
-

-

This post describes various load balancing scenarios seen when deploying gRPC. If you use gRPC with multiple backends, this document is for you.

- -

A large scale gRPC deployment typically has a number of identical back-end instances, and a number of clients. Each server has a certain capacity. Load balancing is used for distributing the load from clients optimally across available servers.

-

- -Read More -


- -

gRPC in Helm

-
May 15, 2017
-

-

Our guest post today comes from Brian Hardock, a software engineer from Deis working on the Helm project.

- -

Helm is the package manager for Kubernetes. Helm provides its users with a customizable mechanism for -managing distributed applications and controlling their deployment.

- -

I have the good fortune to be a member of the phenomenal open-source Kubernetes Helm community serving as -a core contributor. My first day working with the Helm team was spent prototyping the architecture for -the next generation of Helm. By the end of that day, we had procured the preliminary RPC protocol data model -used to enable communication between Helm and its in-cluster server component, Tiller.

-

- -Read More -


- -

Migration to Google Cloud Platform — gRPC & grpc-gateway

-
April 12, 2017
-

-

Our guest post today comes from Miguel Mendez of Yik Yak.

- -

This post was originally a part of the Yik Yak Engineering Blog which focused on sharing the lessons learned as we evolved Yik Yak from early-stage startup code running in Amazon Web Services to an eventual incremental rewrite, re-architecture, and live-migration to Google Cloud Platform.

- -

In our previous blog post we gave an overview of our migration to Google Cloud Platform from Amazon Web Services. In this post we will drill down into the role that gRPC and grpc-gateway played in that migration and share some lessons which we picked up along the way.

-

- -Read More -


- -

Building gRPC services with bazel and rules_protobuf

-
October 13, 2016
-

-

gRPC makes it easier to build high-performance -microservices by providing generated service entrypoints in a variety -of different languages. Bazel complements these -efforts with a capable and fast polyglot build environment.

- -

rules_protobuf extends -bazel and makes it easier develop gRPC services.

-

- -Read More -


- -

gRPC at VSCO

-
September 06, 2016
-

-

Our guest post today comes from Robert Sayre and Melinda Lu of VSCO.

- -

Founded in 2011, VSCO is a community for expression—empowering people to create, discover and connect through images and words. VSCO is in the process of migrating their stack to gRPC.

-

- -Read More -


- -

Why we have decided to move our APIs to gRPC

-
August 29, 2016
-

- Our guest post today comes from Dale Hopkins, CTO of Vendasta. -Vendasta started out 8 years ago as a point solution provider of products for small business. From the beginning we partnered with media companies and agencies who have armies of salespeople and existing relationships with those businesses to sell our software. It is estimated that over 30 million small businesses exist in the United States alone, so scalability of our SaaS solution was considered one of our top concerns from the beginning and it was the reason we started with Google App Engine and Datastore. -

- -Read More -


- -

gRPC Project is now 1.0 and ready for production deployments

-
August 23, 2016
-

- Today, the gRPC project has reached a significant milestone with its 1.0 release. Languages moving to 1.0 include C++, Java, Go, Node, Ruby, Python and C# across Linux, Windows, and Mac. Objective-C and Android Java support on iOS and Android is also moving to 1.0. The 1.0 release means that the core protocol and API surface are now stable with measured performance, stress tested and developers can rely on these APIs and deploy in production, they will follow semantic versioning from here. -

- -Read More -


- -

gRPC with REST and Open APIs

-
May 09, 2016
-

-

Our guest post today comes from Brandon Phillips of CoreOS. CoreOS builds open source projects and products for Linux Containers. Their flagship product for consensus and discovery etcd and their container engine rkt are early adopters of gRPC.

- -

One of the key reasons CoreOS chose gRPC is because it uses HTTP/2, enabling applications to present both a HTTP 1.1 REST/JSON API and an efficient gRPC interface on a single TCP port (available for Go). This provides developers with compatibility with the REST web ecosystem, while advancing a new, high-efficiency RPC protocol. With the recent release of Go 1.6, Go ships with a stable net/http2 package by default.

-

- -Read More -


- -

gRPC - now with easy installation.

-
April 04, 2016
-

-

Today we are happy to provide an update that significantly simplifies the getting started experience for gRPC.

- - -

- -Read More -


- -

Google Cloud PubSub - with the power of gRPC!

-
March 24, 2016
-

-

Google Cloud PubSub is Google’s scalable real-time messaging service that lets users send and receive messages between independent applications. It’s an important part of Google Cloud Platform’s big data offering, and is used by customers worldwide to build their own robust, global services. However, until now, the only way to use the Cloud PubSub API was via JSON over HTTP. That’s all changed with the release of PubSub gRPC alpha. Now users can access PubSub via gRPC and benefit from all the advantages it brings.

-

- -Read More -


- - - - - -
- - - -
- -
All blog posts
- - Dear gRPC

- - The state of gRPC in the browser

- - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

- - Visualizing gRPC Language Stacks

- - gRPC-Web is Generally Available

- - A short introduction to Channelz

- - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

- - gRPC + JSON

- - Take the gRPC Survey!

- - HTTP/2 Smarter At Scale

- - Gracefully clean up in gRPC JUnit tests

- - gRPC ❤ Kotlin

- - So You Want to Optimize gRPC - Part 2

- - So You Want to Optimize gRPC - Part 1

- - gRPC and Deadlines

- - 2018-01-19 gRPC-Go Engineering Practices

- - The gRPC Meetup Kit

- - 2017-08-22 gRPC-Go performance Improvements

- - 2017-08-17 Community Meeting Update

- - Announcing out of the box support for gRPC in the Flatbuffers serialization library.

- - gRPC Load Balancing

- - gRPC in Helm

- - Migration to Google Cloud Platform — gRPC & grpc-gateway

- - Building gRPC services with bazel and rules_protobuf

- - gRPC at VSCO

- - Why we have decided to move our APIs to gRPC

- - gRPC Project is now 1.0 and ready for production deployments

- - gRPC with REST and Open APIs

- - gRPC - now with easy installation.

- - Google Cloud PubSub - with the power of gRPC!

- - gRPC releases Beta, opening door for use in production environments.

- - gRPC Motivation and Design Principles.

- - -
- - - -
- - - - - - - - - - - diff --git a/public/blog/page/4/index.html b/public/blog/page/4/index.html deleted file mode 100644 index 8f1e746..0000000 --- a/public/blog/page/4/index.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - - - - - - - Blogs – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- - -
-
- - -

gRPC releases Beta, opening door for use in production environments.

-
October 26, 2015
-

- -

- The gRPC team is excited to announce the immediate availability of gRPC Beta. This release marks an important point in API stability and going forward most API changes are expected to be additive in nature. This milestone opens the door for gRPC use in production environments. -

- - -

- -Read More -


- -

gRPC Motivation and Design Principles.

-
September 08, 2015
-

- -

Motivation

- -

Google has been using a single general-purpose RPC infrastructure called Stubby to connect the large number of microservices running within and across our data centers for over a decade. Our internal systems have long embraced the microservice architecture gaining popularity today. Having a uniform, cross-platform RPC infrastructure has allowed for the rollout of fleet-wide improvements in efficiency, security, reliability and behavioral analysis critical to supporting the incredible growth seen in that period. -

- - -

- -Read More -


- - - - - -
- - - -
- -
All blog posts
- - Dear gRPC

- - The state of gRPC in the browser

- - gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build

- - Visualizing gRPC Language Stacks

- - gRPC-Web is Generally Available

- - A short introduction to Channelz

- - gRPC on HTTP/2 Engineering a Robust, High Performance Protocol

- - gRPC + JSON

- - Take the gRPC Survey!

- - HTTP/2 Smarter At Scale

- - Gracefully clean up in gRPC JUnit tests

- - gRPC ❤ Kotlin

- - So You Want to Optimize gRPC - Part 2

- - So You Want to Optimize gRPC - Part 1

- - gRPC and Deadlines

- - 2018-01-19 gRPC-Go Engineering Practices

- - The gRPC Meetup Kit

- - 2017-08-22 gRPC-Go performance Improvements

- - 2017-08-17 Community Meeting Update

- - Announcing out of the box support for gRPC in the Flatbuffers serialization library.

- - gRPC Load Balancing

- - gRPC in Helm

- - Migration to Google Cloud Platform — gRPC & grpc-gateway

- - Building gRPC services with bazel and rules_protobuf

- - gRPC at VSCO

- - Why we have decided to move our APIs to gRPC

- - gRPC Project is now 1.0 and ready for production deployments

- - gRPC with REST and Open APIs

- - gRPC - now with easy installation.

- - Google Cloud PubSub - with the power of gRPC!

- - gRPC releases Beta, opening door for use in production environments.

- - gRPC Motivation and Design Principles.

- - -
- - - -
- - - - - - - - - - - diff --git a/public/blog/principles/index.html b/public/blog/principles/index.html deleted file mode 100644 index 7bed337..0000000 --- a/public/blog/principles/index.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - gRPC Motivation and Design Principles. – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC Motivation and Design Principles.

-
Posted on Tuesday, September 08, 2015 - - - - -
-

-

Stubby has many great features - however, it's not based on any standard and is too tightly coupled to our internal infrastructure to be considered suitable for public release. With the advent of SPDY, HTTP/2, and QUIC, many of these same features have appeared in public standards, together with other features that Stubby does not provide. It became clear that it was time to rework Stubby to take advantage of this standardization, and to extend its applicability to mobile, IoT, and Cloud use-cases.

- -

Principles & Requirements

- -

Services not Objects, Messages not References - Promote the microservices design philosophy of coarse-grained message exchange between systems while avoiding the pitfalls of distributed objects and the fallacies of ignoring the network.

- -

Coverage & Simplicity - The stack should be available on every popular development platform and easy for someone to build for their platform of choice. It should be viable on CPU & memory limited devices.

- -

Free & Open - Make the fundamental features free for all to use. Release all artifacts as open-source efforts with licensing that should facilitate and not impede adoption.

- -

Interoperability & Reach - The wire-protocol must be capable of surviving traversal over common internet infrastructure.

- -

General Purpose & Performant - The stack should be applicable to a broad class of use-cases while sacrificing little in performance when compared to a use-case specific stack.

- -

Layered - Key facets of the stack must be able to evolve independently. A revision to the wire-format should not disrupt application layer bindings.

- -

Payload Agnostic - Different services need to use different message types and encodings such as protocol buffers, JSON, XML, and Thrift; the protocol and implementations must allow for this. Similarly the need for payload compression varies by use-case and payload type: the protocol should allow for pluggable compression mechanisms.

- -

Streaming - Storage systems rely on streaming and flow-control to express large data-sets. Other services, like voice-to-text or stock-tickers, rely on streaming to represent temporally related message sequences.

- -

Blocking & Non-Blocking - Support both asynchronous and synchronous processing of the sequence of messages exchanged by a client and server. This is critical for scaling and handling streams on certain platforms.

- -

Cancellation & Timeout - Operations can be expensive and long-lived - cancellation allows servers to reclaim resources when clients are well-behaved. When a causal-chain of work is tracked, cancellation can cascade. A client may indicate a timeout for a call, which allows services to tune their behavior to the needs of the client.

- -

Lameducking - Servers must be allowed to gracefully shut-down by rejecting new requests while continuing to process in-flight ones.

- -

Flow-Control - Computing power and network capacity are often unbalanced between client & server. Flow control allows for better buffer management as well as providing protection from DOS by an overly active peer.

- -

Pluggable - A wire protocol is only part of a functioning API infrastructure. Large distributed systems need security, health-checking, load-balancing and failover, monitoring, tracing, logging, and so on. Implementations should provide extensions points to allow for plugging in these features and, where useful, default implementations.

- -

Extensions as APIs - Extensions that require collaboration among services should favor using APIs rather than protocol extensions where possible. Extensions of this type could include health-checking, service introspection, load monitoring, and load-balancing assignment.

- -

Metadata Exchange - Common cross-cutting concerns like authentication or tracing rely on the exchange of data that is not part of the declared interface of a service. Deployments rely on their ability to evolve these features at a different rate to the individual APIs exposed by services.

- -

Standardized Status Codes - Clients typically respond to errors returned by API calls in a limited number of ways. The status code namespace should be constrained to make these error handling decisions clearer. If richer domain-specific status is needed the metadata exchange mechanism can be used to provide that.

- -

- - -
- - - - - - - - - - diff --git a/public/blog/pubsub/index.html b/public/blog/pubsub/index.html deleted file mode 100644 index c58b210..0000000 --- a/public/blog/pubsub/index.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - Google Cloud PubSub - with the power of gRPC! – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Google Cloud PubSub - with the power of gRPC!

-
Posted on Thursday, March 24, 2016 - - - - -
-

-

Google Cloud PubSub is Google’s scalable real-time messaging service that lets users send and receive messages between independent applications. It’s an important part of Google Cloud Platform’s big data offering, and is used by customers worldwide to build their own robust, global services. However, until now, the only way to use the Cloud PubSub API was via JSON over HTTP. That’s all changed with the release of PubSub gRPC alpha. Now users can access PubSub via gRPC and benefit from all the advantages it brings.

- -

Alpha instructions and gRPC code are now available for gRPC PubSub in Python and Java.

- -

But what if you want to use this service now with gRPC in another language - C#, say, or Ruby? Once you have a Google account, with a little bit of extra work you can do that too! You can use the tools and the instructions on our site to generate and use your own gRPC client code from the PubSub service’s .proto file, available from GitHub.

- -

Read the full Google Cloud PubSub announcement

- -

Find out more about using Google Cloud PubSub

-

- - -
- - - - - - - - - - diff --git a/public/blog/state-of-grpc-web/index.html b/public/blog/state-of-grpc-web/index.html deleted file mode 100644 index 6d159b0..0000000 --- a/public/blog/state-of-grpc-web/index.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - - - - - - - The state of gRPC in the browser – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

The state of gRPC in the browser

-
Posted on Tuesday, January 08, 2019 - by - - Johan Brandhorst - -
-

-

This is a guest post by -Johan Brandhorst, Software Engineer at -InfoSum.

- -

gRPC 1.0 was released in August 2016 and has since grown to become one of the -premier technical solutions for application communications. It has been adopted -by startups, enterprise companies, and open source projects worldwide. -Its support for polyglot environments, focus on performance, type safety, and -developer productivity has transformed the way developers design their -architectures.

- -

So far the benefits have largely only been available to mobile -app and backend developers, whilst frontend developers have had to continue to -rely on JSON REST interfaces as their primary means of information exchange. -However, with the release of gRPC-Web, gRPC is poised to become a valuable -addition in the toolbox of frontend developers.

- -

In this post, I’ll describe some of the history of gRPC in the browser, explore -the state of the world today, and share some thoughts on the future.

- -

Beginnings

- -

In the summer of 2016, both a team at Google and -Improbable1 independently started working on -implementing something that could be called “gRPC for the browser”. They soon -discovered each other’s existence and got together to define a -spec2 for the new protocol.

- -

The gRPC-Web Spec

- -

It is currently impossible to implement the HTTP/2 gRPC -spec3 in the browser, as there is simply no browser -API with enough fine-grained control over the requests. For example: there is -no way to force the use of HTTP/2, and even if there was, raw HTTP/2 frames are -inaccessible in browsers. The gRPC-Web spec starts from the point of view of the -HTTP/2 spec, and then defines the differences. These notably include:

- - - -

The Tech

- -

The basic idea is to have the browser send normal HTTP requests (with Fetch or -XHR) and have a small proxy in front of the gRPC server to translate the -requests and responses to something the browser can use.

- -

The role of the gRPC-Web proxy

- -

The Two Implementations

- -

The teams at Google and Improbable both went on to implement the spec in two -different repositories5,6, -and with slightly different implementations, such that neither was entirely -conformant to the spec, and for a long time neither was compatible with the -other’s proxy7,8.

- -

The Improbable gRPC-Web client9 is implemented in -TypeScript and available on npm as @improbable-eng/grpc-web10. -There is also a Go proxy available, both as a package that can be imported into -existing Go gRPC servers11, and as a standalone -proxy that can be used to expose an arbitrary gRPC server to a gRPC-Web -frontend12.

- -

The Google gRPC-Web client13 is implemented in -JavaScript using the Google Closure library14 base. -It is available on npm as grpc-web15. It originally -shipped with a proxy implemented as an NGINX -extension16, but has since doubled down on an Envoy -proxy HTTP filter17, which is available in all -versions since v1.4.0.

- -

Feature Sets

- -

The gRPC HTTP/2 implementations all support the four method types: unary, -server-side, client-side, and bi-directional streaming. However, the gRPC-Web -spec does not mandate any client-side or bi-directional streaming support -specifically, only that it will be implemented once WHATWG -Streams18 are implemented in browsers.

- -

The Google client supports unary and server-side streaming, but only when used -with the grpcwebtext mode. Only unary requests are fully supported in the -grpcweb mode. These two modes specify different ways to encode the protobuf -payload in the requests and responses.

- -

The Improbable client supports both unary and server-side streaming, and has an -implementation that automatically chooses between XHR and Fetch based on the -browser capabilities.

- -

Here’s a table that summarizes the different features supported:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Client / FeatureTransportUnaryServer-side streamsClient-side & bi-directional streaming
ImprobableFetc️h/XHR ️✔️✔️19
Google (grpcwebtext)XHR ️✔️✔️
Google (grpcweb)XHR ️✔️20
- -

For more information on this table, please see -my compatibility test repo on github.

- -

The compatibility tests may evolve into some automated test framework to enforce -and document the various compatibilities in the future.

- -

Compatibility Issues

- -

Of course, with two different proxies also come compatibility issues. -Fortunately, these have recently been ironed out, so you can expect to use -either client with either proxy.

- -

The Future

- -

The Google implementation announced version 1.0 and general availability in -October 201821 and has published a roadmap of future -goals22, including:

- - - -

Google is looking for feedback on what features are important to the community, -so if you think any of these are particularly valuable to you, then please fill -in their survey23.

- -

Recent talks between the two projects have agreed on promoting the Google client -and Envoy proxy as preferred solutions for new users. The Improbable client and -proxy will remain as alternative implementations of the spec without the -Google Closure dependency, but should be considered experimental. A migration -guide will be produced for existing users to move to the Google client, and the -teams are working together to converge the generated APIs.

- -

Conclusion

- -

The Google client will continue to have new features and fixes implemented at a -steady pace, with a team dedicated to its success, and it being the official -gRPC client. It doesn’t have Fetch API support like the Improbable client, but -if this is an important feature for the community, it will be added. The Google -team and the greater community are collaborating on the official client to the -benefit of the gRPC community at large. Since the GA announcement the community -contributions to the Google gRPC-Web repo has increased dramatically.

- -

When choosing between the two proxies, there’s no difference in capability, so -it becomes a matter of your deployment model. Envoy will suit some -scenarios, while an in-process Go proxy has its own advantages.

- -

If you’re getting started with gRPC-Web today, first try the Google client. It -has strict API compatibility guarantees and is built on the rock-solid Google -Closure library base used by Gmail and Google Maps. If you need Fetch API -memory efficiency or experimental websocket client-side and bi-directional -streaming, the Improbable client is a good choice, and it will continue to be -used and maintained by Improbable for the foreseeable future.

- -

Either way, gRPC-Web is an excellent choice for web developers. It brings the -portability, performance, and engineering of a sophisticated protocol into the -browser, and marks an exciting time for frontend developers!

- -

References

- -
    -
  1. https://improbable.io/games/blog/grpc-web-moving-past-restjson-towards-type-safe-web-apis
  2. -
  3. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md
  4. -
  5. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
  6. -
  7. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
  8. -
  9. https://github.com/improbable-eng/grpc-web
  10. -
  11. https://github.com/grpc/grpc-web
  12. -
  13. https://github.com/improbable-eng/grpc-web/issues/162
  14. -
  15. https://github.com/grpc/grpc-web/issues/91
  16. -
  17. https://github.com/improbable-eng/grpc-web/tree/master/ts
  18. -
  19. https://www.npmjs.com/package/@improbable-eng/grpc-web
  20. -
  21. https://github.com/improbable-eng/grpc-web/tree/master/go/grpcweb
  22. -
  23. https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy
  24. -
  25. https://github.com/grpc/grpc-web/tree/master/javascript/net/grpc/web
  26. -
  27. https://developers.google.com/closure/
  28. -
  29. https://www.npmjs.com/package/grpc-web
  30. -
  31. https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway
  32. -
  33. https://www.envoyproxy.io/docs/envoy/latest/configuration/http_filters/grpc_web_filter
  34. -
  35. https://streams.spec.whatwg.org/
  36. -
  37. The Improbable client supports client-side and -bi-directional streaming with an experimental websocket transport. This is -not part of the gRPC-Web spec, and is not recommended for production use.
  38. -
  39. grpcweb allows server streaming methods to be called, but -it doesn’t return data until the stream has closed.
  40. -
  41. https://grpc.io/blog/grpc-web-ga
  42. -
  43. https://github.com/grpc/grpc-web/blob/master/ROADMAP.md
  44. -
  45. https://docs.google.com/forms/d/1NjWpyRviohn5jaPntosBHXRXZYkh_Ffi4GxJZFibylM
  46. -
-

- - -
- - - - - - - - - - diff --git a/public/blog/take-the-grpc-survey/index.html b/public/blog/take-the-grpc-survey/index.html deleted file mode 100644 index 8c48421..0000000 --- a/public/blog/take-the-grpc-survey/index.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - Take the gRPC Survey! – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Take the gRPC Survey!

-
Posted on Tuesday, August 14, 2018 - by - - Kailash Sethuraman - -
-

-

The gRPC Project wants your feedback!

- -

The gRPC project is looking for feedback to improve the gRPC experience. To do this, we are running a gRPC user survey. We invite you to participate and provide input that will help us better plan and prioritize.

- -

gRPC User Survey

- -

Who : If you currently use gRPC, have used gRPC in the past, or have any interest in it, we would love to hear from you.

- -

Where: Please take this 15 minute survey by Friday, 24th August.

- -

Why: gRPC is a broadly applicable project with a variety of use cases. We want to use this survey to help us understand what works well, and what needs to be fixed.

- -

Spread the word!

- -

Please help us spread the word on this survey by posting it on your social networks and sharing with your friends. Every single feedback is precious, and we would like as much of it as possible!

- -

Survey Short link: http://bit.ly/gRPC18survey -

-

- - -
- - - - - - - - - - diff --git a/public/blog/vendastagrpc/index.html b/public/blog/vendastagrpc/index.html deleted file mode 100644 index c118673..0000000 --- a/public/blog/vendastagrpc/index.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - - - - - Why we have decided to move our APIs to gRPC – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Why we have decided to move our APIs to gRPC

-
Posted on Monday, August 29, 2016 - by - - Dale Hopkins - -
-

-

Our guest post today comes from Dale Hopkins, CTO of Vendasta.

- -

Vendasta started out 8 years ago as a point solution provider of products for small business. From the beginning we partnered with media companies and agencies who have armies of salespeople and existing relationships with those businesses to sell our software. It is estimated that over 30 million small businesses exist in the United States alone, so scalability of our SaaS solution was considered one of our top concerns from the beginning and it was the reason we started with Google App Engine and Datastore. This solution worked really well for us as our system scaled from hundreds to hundreds of thousands of end users. We also scaled our offering from a point solution to an entire platform with multiple products and the tools for partners to manage their sales of those products during this time.

- -

All throughout this journey Python GAE served our needs well. We exposed a number of APIs via HTTP + JSON for our partners to automate tasks and integrate their other systems with our products and platform. However, in 2016 we introduced the Vendasta Marketplace. This marked a major change to our offering, which depended heavily on having 3rd party vendors use our APIs to deliver their own products in our platform. This was a major change because our public APIs provide an upper-bound on 3rd-party applications, and made us realize that we really needed to make APIs that were amazing, not just good.

- -

The first optimization that we started with was to use the Go programming language to build endpoints that handled higher throughput with lower latency than we could get with Python. On some APIs this made an incredible difference: we saw 50th percentile response times to drop from 1200 ms to 4 ms, and even more spectacularly 99th percentile response times drop from 30,000 ms to 12 ms! On other APIs we saw a much smaller, but still significant difference.

- -

The second optimization we used was to replicate large portions of our Datastore data into ElasticSearch. ElasticSearch is a fundamentally different storage technology to Datastore, and is not a managed service, so it was a big leap for us. But this change allowed us to migrate almost all of our overnight batch-processing APIs to real-time APIs. We had tried BigQuery, but it’s query processing times meant that we couldn’t display things in real time. We had tried cloudSQL, but there was too much data for it to easily scale. We had tried the appengine Search API, but it has limitations with result sets over 10,000. We instead scaled up our ElasticSearch cluster using Google Container Engine and with it’s powerful aggregations and facet processing our needs were easily met. So with these first two solutions in place, we had made meaningful changes to the performance of our APIs.

- -

The last optimization we made was to move our APIs to gRPC. This change was much more extensive than the others as it affected our clients. Like ElasticSearch, it represents a fundamentally different model with differing performance characteristics, but unlike ElasticSearch we found it to be a true superset: all of our usage scenarios were impacted positively by it.

- -

The first benefit we saw from gRPC was the ability to move from publishing APIs and asking developers to integrate with them, to releasing SDKs and asking developers to copy-paste example code written in their language. This represents a really big benefit for people looking to integrate with our products, while not requiring us to hand-roll entire SDKs in the 5+ languages our partners and vendors use. It is important to note that we still write light wrappers over the generated gRPC SDKs to make them package-manager friendly, and to provide wrappers over the generated protobuf structures.

- -

The second benefit we saw from gRPC was the ability to break free from the call-and-response architecture necessitated by HTTP + JSON. gRPC is built on top of HTTP/2, which allows for client-side and/or server-side streaming. In our use cases, this means we can lower the time to first display by streaming results as they become ready on the server (server-side streaming). We have also been investigating the potential to offer very flexible create endpoints that easily support bulk ingestion with bi-directional streaming, this would mean we would allow the client to asynchronously stream results, while the server would stream back statuses allowing for easy checkpoint operations while not slowing upload speeds to wait for confirmations. We feel that we are just starting to see the benefits from this feature as it opens up a totally new model for client-server interactions that just wasn’t possible with HTTP.

- -

The third benefit was the switch from JSON to protocol buffers, which works very well with gRPC. This improves serialization and deserialization times; which is very significant to some of our APIs, but appreciated on all of them. The more important benefit comes from the explicit format specification of proto, meaning that clients receive typed objects rather than free-form JSON. Because of this, our clients can reap the benefits of auto-completion in their IDEs, type-safety if their language supports it, and enforced compatibility between clients and servers with differing versions.

- -

The final benefit of gRPC was our ability to quickly spec endpoints. The proto format for both data and service definition greatly simplifies defining new endpoints and finally allows the succinct definition of endpoint contracts. This means we are much better able to communicate endpoint specifications between our development teams. gRPC means that for the first time at our company we are able to simultaneously develop the client and the server side of our APIs! This means our latency to produce new APIs with the accompanying SDKs has dropped dramatically. Combined with code generation, it allows us to truly develop clients and servers in parallel.

- -

Our experience with gRPC has been positive, even though it does not eliminate the difficulty of providing endpoints to partners and vendors, and address all of our performance issues. However, it does make improvements to our endpoint performance, integration with those endpoints, and even in delivery of SDKs.

- -

- - -
- - - - - - - - - - diff --git a/public/blog/vscogrpc/index.html b/public/blog/vscogrpc/index.html deleted file mode 100644 index 03080ca..0000000 --- a/public/blog/vscogrpc/index.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - gRPC at VSCO – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

gRPC at VSCO

-
Posted on Tuesday, September 06, 2016 - by - - Robert Sayre and Melinda Lu - -
-

-

Our guest post today comes from Robert Sayre and Melinda Lu of VSCO.

- -

Founded in 2011, VSCO is a community for expression—empowering people to create, discover and connect through images and words. VSCO is in the process of migrating their stack to gRPC.

- -

In 2015, user growth forced VSCO down a familiar path. A monolithic PHP application in existence since the early days of the company was exhibiting performance problems and becoming difficult to maintain. We experimented with some smaller services in node.js, Go, and Java. At the same time, a larger messaging service for email, push messages, and in-app notifications was built in Go. Taking a first step away from JSON, we chose Protocol Buffers as the serialization format for this system.

- -

Today, VSCO has largely settled on Go for new services. There are exceptions, particularly where a mature JVM solution is available for a given problem. Additionally, VSCO uses node.js for web applications, often with server-side React. Given that mix of languages, services, and some future data pipeline work detailed below, VSCO settled on gRPC and Protocol Buffers as the most practical solution for interprocess communication. A gradual migration from JSON over HTTP/1.1 APIs to gRPC over HTTP/2 is underway and going well. That said, there have been issues with the maturity of the PHP implementation relative to other languages.

- -

Protocol buffers have been particularly valuable in building out our data ecosystem, where we rely on them to standardize and allow safe evolution of our data schemas in a language-agnostic way. As one example, we’ve built a Go service that feeds off our MySQL and MongoDB database replication logs and transforms backend database changes into a stream of immutable events in Kafka, with each row- or document-change event encoded as a protocol buffer. This database event stream allows us to add real-time data consumers as desired, without impacting production traffic and without having to coordinate with other systems. By processing all database events into protocol buffers en-route to Kafka, we can ensure that data is encoded in a uniform way that makes it easy to consume and use from multiple languages. Our implementation of MySQL-binary-log and Mongo-oplog tailers are available on GitHub.

- -

Elsewhere in our data pipeline, we’ve begun using gRPC and protocol buffers to deliver behavioral events from our iOS and Android clients to a Go ingestion service, which then publishes these events to Kafka. To support this high-volume use case, we needed (1) a performant, fault-tolerant, language-agnostic RPC framework, (2) a way to ensure data compatibility as our product evolves, and (3) horizontally-scalable infrastructure. We’ve found gRPC, protocol buffers, and Go services running in Kubernetes a good fit for all three. As this was our first client-facing Go gRPC service, we did experience some new points of friction — in particular, load-balancer support and amenities like curl-like debugging have been lagging due to the youth of the HTTP/2 ecosystem. However, the ease of defining services with the gRPC IDL, using built-in architecture like interceptors, and scaling with Go have made the tradeoffs worthwhile.

- -

As a first step in bringing gRPC to our mobile clients, we’ve shipped telemetry code in our iOS and Android apps. As of gRPC 1.0, this process is relatively straightforward. They only post events to our servers so far, and don’t do much with gRPC responses. The previous implementation was based on JSON, and our move to a single protocol buffer definition of our events uncovered a bunch of subtle bugs and differences between the clients.

- -

One slight roadblock we ran into was the need for our clients to maintain compatibility with our JSON implementation as we ramp up, and for integration with vendor SDKs. This required a little bit of key-value coding on iOS, but it got more difficult on Android. We ended up having to write a protobuf compiler plugin to get the reflection features we needed while maintaining adequate performance. Drawing from that experience, we’ve made a concise example protoc plugin built with Bazel available on GitHub.

- -

As more and more of our data becomes available in protocol buffer form, we plan to build upon this unified schema to expand our machine-learning and analytics systems. For example, we write our Kafka database replication streams to Amazon S3 as Apache Parquet, an efficient columnar disk-storage format. Parquet has low-level support for protocol buffers, so we can use our existing data definitions to write optimized tables and do partial deserializations where desired.

- -

From S3, we run computations on our data using Apache Spark, which can use our protocol buffer definitions to define types. We’re also building new machine-learning applications with TensorFlow. It uses protocol buffers natively and allows us to serve our models as gRPC services with TensorFlow Serving.

- -

So far, we’ve had good luck with gRPC and Protocol Buffers. They don’t eliminate every integration headache. However it’s easy to see how they help our engineers avoid writing a lot of boilerplate RPC code, while side-stepping the endless data-quality papercuts that come with looser serialization formats.

-

- - -
- - - - - - - - - - diff --git a/public/blog/yygrpc/index.html b/public/blog/yygrpc/index.html deleted file mode 100644 index d6ec6e8..0000000 --- a/public/blog/yygrpc/index.html +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - Migration to Google Cloud Platform — gRPC & grpc-gateway – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Blog
-
-
-
- -
-

Migration to Google Cloud Platform — gRPC & grpc-gateway

-
Posted on Wednesday, April 12, 2017 - by - - Miguel Mendez - -
-

-

Our guest post today comes from Miguel Mendez of Yik Yak.

- -

This post was originally a part of the Yik Yak Engineering Blog which focused on sharing the lessons learned as we evolved Yik Yak from early-stage startup code running in Amazon Web Services to an eventual incremental rewrite, re-architecture, and live-migration to Google Cloud Platform.

- -

In our previous blog post we gave an overview of our migration to Google Cloud Platform from Amazon Web Services. In this post we will drill down into the role that gRPC and grpc-gateway played in that migration and share some lessons which we picked up along the way.

- -

Most people have REST APIs, don’t you? What’s the problem?

- -

Yes, we actually still have REST APIs that clients use because migrating the client APIs was out of scope. To be fair, you can make REST APIs work and there are a lot of useful REST APIs out there. Having said that, the issues that we had with REST lie in the details.

- -

No Canonical REST Specification

- -

There is no single REST specification that is canonical. There are best practices, but no true canon. For that reason, there isn’t unanimous agreement on when to use specific HTTP methods and response codes. Beyond that, not all of the possible HTTP methods and response codes are supported across all platforms… This forces REST API implementers to compensate for these deficiencies using techniques that work for them but create more variance in REST APIs across the board. At best, REST APIs are really REST-ish dialects.

- -

Harder on Developers

- -

REST APIs aren’t exactly great from a developer’s standpoint either. -First, because REST is tied to HTTP there is no simple mapping to an API in my language of choice. If I’m using Go or Java there is no “interface” that I can use in my code to stub it out. I can create one, but it is extra-linguistic to the REST API definition.

- -

Second, REST APIs spread information that is necessary to interpreting the intent of the request across various components of the request. You have the HTTP method, the request URI, the request payload, and it can get even more complicated if request headers are involved in the semantics.

- -

Third, it is great that I can use curl from the command line to hit an API, but it comes at the cost of having to shoehorn the API into that ecosystem. Normally that use case only matters for letting people quickly try out an API — and if that is high on your list of requirements then by all means feel free to use REST… Just keep it simple.

- -

No Declarative REST API Description

- -

The fourth problem with a REST APIs is that, at least until Swagger arrived on the scene, there was no declarative way to define a REST API and include type information. It may sound pedantic, but there are legitimate reasons to want a proper definition that includes type information in general. To reinforce the point, look at the lines of PHP server code below, which were extracted from various files, that set the “hidePin” field on “yak” which was then returned to the client. The actual line of code that executed on the server was a function of multiple parameters, so imagine that the one which was run was basically chosen at random:

-
    // Code omitted…
-    $yak->hidePin=false;
-    
-    // Code omitted…
-    $yak->hidePin=true;
-    
-    // Code omitted…
-    $yak->hidePin=0;
-    
-    // Code omitted…
-    $yak->hidePin=1;
-

What is the type of the field hidePin? You cannot say for certain. It could be a boolean or an integer or whatever happens to have been written there by the server, but in any case now your clients have to be able to deal with these possibilities which makes them more complicated.

- -

Problems can also arise when the client’s definition of a type varies from that which the server expects. Have a look at the server code below which processed a JSON payload sent up by a client:

-
    // Code omitted…
-    switch ($fieldName) {
-      // Code omitted…
-      case “recipientID”:
-      // This is being added because iOS is passing the recipientID
-      // incorrectly and we still want to capture these events
-      // … expected fall through …
-      
-      case “Recipientid”:
-        $this->yakkerEvent->recipientID = $value;
-        break;
-      // Code omitted…
-    }
-    // Code omitted…
-

In this case, the server had to deal with an iOS client that sent a JSON object whose field name used unexpected casing. Again, not insurmountable but all of these little disconnects compound and work together to steal time away from the problems that really move the ball down the field.

- -

gRPC can address the issues with REST…

- -

If you’re not familiar with gRPC, it’s a “high performance, open-source universal remote procedure call (RPC) framework” that uses Google Protocol Buffers as the Interface Description Language (IDL) for describing a service interface as well as the structure of the messages exchanged. This IDL can then be compiled to produce language-specific client and server stubs. In case that seemed a little obtuse, I’ll zoom into the aspects that are important.

- -

gRPC is Declarative, Strongly-Typed, and Language Independent

- -

gRPC descriptions are written using an Interface Description Language that is independent of any specific programming language, yet its concepts map onto the supported languages. This means that you can describe your ideal service API, the messages that it supports, and then use “protoc”, the protocol compiler, to generate client and server stubs for your API. Out of the box, you can produce client and server stubs in C/C++, C#, Node.js, PHP, Ruby, Python, Go and Java. You can also get additional protoc plugins which can create stubs for Objective-C and Swift.

- -

Those issues that we had with “hidePin” and “recipientID” vs.”Recipientid” fields above go away because we have a single, canonical declaration that establishes the types used, and the language-specific code generation ensures that we don’t have typos in the client or server code regardless of their implementation language.

- -

gRPC Means No hand-rolling of RPC Code is Required

- -

This is a very powerful aspect of the gRPC ecosystem. Often times developers will hand roll their RPC code because it just seems more straightforward. However, as the number of types of clients that you need to support increases, the carrying costs of this approach also increase non-linearly. -Imagine that you start off with a service that is called from a web browser. At some point down the road, the requirements are updated and now you have to support Android and iOS clients. Your server is likely fine, but the clients now need to be able to speak the same RPC dialect and often times there are differences that creep in. Things can get even worse if the server has to compensate for the differences amongst the clients. -On the other hand, using gRPC you just add the protocol compiler plugins and they generate the Android and iOS client stubs. This cuts out a whole class of problems. As a bonus, if you don’t modify the generated code — and you should not have to — then any performance improvements in the generated code will be picked up.

- -

gRPC has Compact Serialization

- -

gRPC uses Google protocol buffers to serialize messages. This serialization format is very compact because, among other things, field names are not included in the serialized form. Compare this to a JSON object where each instance of an object carries a full copy of its field names, includes extra curly braces, etc. For a low-volume application this may not be an issue, but it can add up quickly.

- -

gRPC Tooling is Extensible

- -

Another very useful feature of the gRPC framework is that it is extensible. If you need support for a language that is not currently supported, there is a way to create plugins for the protocol compiler that allows you to add what you need.

- -

gRPC Supports Contract Updates

- -

An often overlooked aspect of service APIs is how they may evolve over time. At best, this is often a secondary consideration. If you are using gRPC, and you adhered to a few basic rules, your messages can be forward and backward compatible.

- -

Grpc-gateway — because REST will be with us for a while…

- -

You’re probably thinking: gRPC is great but I have a ton of REST clients to deal with. Well, there is another tool in this ecosystem and it is called grpc-gateway. Grpc-gateway “generates a reverse-proxy server which translates a RESTful JSON API into gRPC”. So if you want to support REST clients you can, and it doesn’t cost you any real extra effort. -If your existing REST clients are pretty far from the normal REST APIs, you can use custom marshallers with grpc-gateway to compensate.

- -

Migration and gRPC + grpc-gateway

- -

As mentioned previously, we had a lot of PHP code and REST endpoints which we wanted to rework as part of the migration. By using the combination of gRPC and grpc-gateway, we were able to define gRPC versions of the legacy REST APIs and then use grpc-gateway to expose the exact REST endpoints that clients were used to. With these alternative implementations in place we were able to move traffic between the old and new systems using combinations of DNS updates as well as our Experimentation and Configuration System without causing any disruption to the existing clients. We were even able to leverage the existing test suites to verify functionality and establish parity between the old and new systems. -Lets walk through the pieces and how they fit together.

- -

gRPC IDL for “/api/getMessages”

- -

Below is the gRPC IDL that we defined to mimic the legacy Yik Yak API in GCP. We’ve simplified the example to only contain the “/api/getMessages” endpoint which clients use to get the set of messages centered around their current location.

-
// APIRequest Message — sent by clients
-message APIRequest {
-  // userID is the ID of the user making the request
-  string userID = 1;
-  // Other fields omitted for clarity…
-}
-
-// APIFeedResponse contains the set of messages that clients should
-// display.
-message APIFeedResponse {
-  repeated APIPost messages = 1;
-  // Other fields omitted for clarity…
-}
-
-// APIPost defines the set of post fields returned to the clients.
-message APIPost {
-  string messageID = 1;
-  string message = 2;
-  // Other fields omitted for clarity…
-}
-
-// YYAPI service accessed by Android, iOS and Web clients.
-service YYAPI {
-  // Other endpoints omitted…
-  
-  // APIGetMessages returns the list of messages within a radius of
-  // the user’s current location.
-  rpc APIGetMessages (APIRequest) returns (APIFeedResponse) {
-    option (google.api.http) = {
-      get: /api/getMessages // Option tells grpc-gateway that an HTTP
-                              // GET to /api/getMessages should be
-                              // routed to the APIGetMessages gRPC
-                              // endpoint.
-    };
-  }
-  
-  // Other endpoints omitted…
-}
-

Protoc Generated Go Interfaces for YYAPI Service

- -

The IDL above is then compiled to Go files by the protoc compiler to produce client proxies and server stubs as below.

-
// Client API for YYAPI service
-type YYAPIClient interface {
-  APIGetMessages(ctx context.Context, in *APIRequest, opts ...grpc.CallOption) (*APIFeedResponse, error)
-}
-
-// NewYYAPIClient returns an implementation of the YYAPIClient interface  which 
-// clients can use to call the gRPC service.
-func NewYYAPIClient(cc *grpc.ClientConn) YYAPIClient {
-  // Code omitted for clarity..
-}
-
-// Server API for YYAPI service
-type YYAPIServer interface {
-  APIGetMessages(context.Context, *APIRequest) (*APIFeedResponse, error)
-}
-
-// RegisterYYAPIServer registers an implementation of the YYAPIServer with an
-// existing gRPC server instance.
-func RegisterYYAPIServer(s *grpc.Server, srv YYAPIServer) {
-  // Code omitted for clarity..
-}
-

Grpc-gateway Generated Go-code for REST Reverse Proxy of YYAPI Service

- -

By using the google.api.http option in our IDL above, we tell the grpc-gateway system that it should route HTTP GETs for “/api/getMessages” to the APIGetMessages gRPC endpoint. In turn, it creates the HTTP to gRPC reverse proxy and allows you to set it up by calling the generated function below.

-
// RegisterYYAPIHandler registers the http handlers for service YYAPI to “mux”.
-// The handlers forward requests to the grpc endpoint over “conn”.
-func RegisterYYAPIHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-  // Code omitted for clarity
-}
-

So again, from a single gRPC IDL description you can obtain client and server interfaces and implementation stubs in your language of choice as well as REST reverse proxies for free.

- -

gRPC — I heard there were some rough edges?

- -

We started working with gRPC for Go late in Q1 of 2016 and there were definitely some rough edges at the time.

- -

Early Adopter Issues

- -

We ran into Issue 674, a resource leak inside of the Go gRPC client code which could cause gRPC transports to hang when under heavy load. The gRPC team was very responsive and the fix was merged into the master branch within days.

- -

We ran into a resource leak in the generated code for grpc-gateway. However, by the time we found that issue, it had already been fixed by that team and merged into master.

- -

The last early-adopter type issue that we ran into was around the Go’s gRPC client not supporting the GOAWAY packet that was part of the gRPC protocol spec. Fortunately, this one did not impact us in production. It only manifested during the repo case we had put together for Issue 674.

- -

All in all this was fairly reasonable given how early we were.

- -

Load Balancing

- -

Now, if you are going to use gRPC this is definitely one area that you need to think through carefully. By default, gRPC uses HTTP2 instead of HTTP1. HTTP2 is able to open a connection to a server and reuse it for multiple requests among other things. If you use it in that mode, you won’t distribute requests amongst all of the servers in your load balancing pool. At the time that we executing the migration, existing load balancers didn’t handle HTTP2 traffic very well if at all.

- -

At the time the gRPC team didn’t have a Load Balancing Proposal, so we burned a lot of cycles trying to force our system to do some type of client-side load balancing. In the end, since most of our raw gRPC communications took place within the data center, and everything was deployed using Kubernetes, it was simpler to dial the remote server every time thereby forcing the system to spread the load out amongst the servers in the Kubernetes Service. Given our setup it only added about 1 ms to the overall response time, so it was a simple work around.

- -

So was that the end of the load balancing issues? Not exactly. Once we had our basic gRPC-based system up and running we started running load tests against it, and noticed some interesting behaviors. Below is the per gRPC server CPU load graph over time, do you notice anything curious about it?

- -

- -

The server with the heaviest load was running at around 50% CPU, while the most lightly loaded server was running at around 20% CPU even after several minutes of warmup. It turned out that even though we were dialing every time, we had an nghttp2 ingress as part of our network topology which would tend to send inbound requests to servers to whom it had already connected and thereby causing uneven distribution. After removing the nghttp2 ingress, our CPU graphs showed much less variance in the load distribution.

- -

- -

Conclusion

- -

REST APIs have their issues, but they are not going away anytime soon. If you are up for trying something a little cleaner, then definitely consider using gRPC (along with grpc-gateway if you still need to expose a REST API). Even though we hit some issues early on, gRPC was a net gain for us. It gave us a path forward to more tightly defined APIs. It also allowed us to stand up new implementations of the legacy REST APIs in GCP which teed us up to seamlessly migrate traffic from the AWS implementations to the new GCP ones in a controlled manner.

- -

Having discussed our use of Go, gRPC and Google Cloud Platform, we are ready to discuss how we built a new geo store on top of Google Bigtable and the Google S2 Library — the subject of our next post.

-

- - -
- - - - - - - - - - diff --git a/public/categories/index.html b/public/categories/index.html deleted file mode 100644 index 6c0724e..0000000 --- a/public/categories/index.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - gRPC - - - - - - - - - - - - - - - - - -
-
-
- - - -
-
-
-

Categories

-
- - - -
- -
    - - -
-
- - - - - - - - - - diff --git a/public/categories/index.xml b/public/categories/index.xml deleted file mode 100644 index b1282a1..0000000 --- a/public/categories/index.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Categories on gRPC - https://cjyabraham.github.io/categories/ - Recent content in Categories on gRPC - Hugo -- gohugo.io - en-us - - - - - - \ No newline at end of file diff --git a/public/community/index.html b/public/community/index.html deleted file mode 100644 index c8fac25..0000000 --- a/public/community/index.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - Community – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Community
-
-
-
- -
- -
-
-

gRPC has an active community of developers who are using, enhancing and building valuable integrations with other software projects. We’d love your help to improve and extend the project. You can reach us via Mailing list, Gitter channel, Twitter to start engaging with the project and its members. -

- -
-

Contribute on Github

-

gRPC has an active community of developers who are using, enhancing and building valuable integrations with other software projects. We are always looking for active contributors in gRPC and gRPC Ecosystem. Here are a few areas where we would love community contribution in grpc project. Be sure to follow our community addition guidelines.

- -
-
-
- - - -

Or shortcut to: C, C++, Node.js, Python, Ruby, Objective-C, PHP, and C# -

-
-
-
-
- - - -

For Android Java and Java.

-
-
-
-
- - - -

For the Go implementation

-
-
-
- More on how to contribute to gRPC Documentation > -
- -
-

Mailing List

-

Any questions or suggestions? Just want to be in the loop of what is going on with the project? Join the mailing list -

- -
-

Join gRPC Ecosystem

-

We have an organization for all valuable projects around gRPC in the gRPC Ecosystem. The goal is to have all projects around gRPC (showing integrations with other projects or building utilities on top of gRPC) to be showcased here. If you have a new project you would like to add to gRPC Ecosystem, please fill up the gRPC Ecosystem Project Request form. Please read the contribution guidelines for gRPC Ecosystem before submitting. -

- -
-

Gitter Channel

-

Join other developers and users on the gRPC Gitter channel

-
- - -
-

Reddit

-

Join the subreddit

-
- -
-

Community Meetings

-

We hold a community video conference every other week. It's a way to discuss the status of work and show off things the community is working on. Meeting information and notes can be found at bit.ly/grpcmeetings.

-
- -
-
- -
- - - - - - - - - - diff --git a/public/contribute/index.html b/public/contribute/index.html deleted file mode 100644 index 027a0de..0000000 --- a/public/contribute/index.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - Contribute – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Contribute
-
-
-
- -
-
-
- - To contribute to gRPC documentation, please fork the GitHub gRPC repository  and start submitting pull requests. - -
-

Contribution guidelines for gRPC

- -

We welcome contributions to either of our three core repositories. gRPC, gRPC Java and gRPC Go.

- - - -
- -
-

Contribution guidelines for gRPC Ecosystem

- -

gRPC Ecosystem is a different organization where we collect and curate valuable integrations of other projects with gRPC. You can propose a new project for it by filling up the Propose new project form.

- - - - -
-

Edit our site on github

- -

Click the below button to visit the repo for our site. You can then click the "Fork" button in the upper-right area of the screen to create a copy of our site on your GitHub account called a "fork." Make any changes you want in your fork, and when you are ready to send those changes to us, go to the index page for your fork and click "New Pull Request" to let us know about it.

- - -
- -
-

Being a member of the gRPC organization on github

- -

Being an organization member is not required for the vast majority of the contributions. Membership is required for certain administrative tasks such as accepting a pull request, or closing issues. If you wish to be part of the gRPC organization on github, please get in touch with us. Please note that in order to be part of the organization, your github account needs to have two factor security enabled.

- -
-

-

-

-
-
-
-
- -
- - - - - - - - - - diff --git a/public/css/style.css b/public/css/style.css deleted file mode 100755 index 9c61cab..0000000 --- a/public/css/style.css +++ /dev/null @@ -1,1224 +0,0 @@ -/* -contentDiv { - background-color: orange; - height: 200px; - position: relative; - width: 200px; -} -*/ - -table { - margin-top: 3%; - margin-bottom: 3%; - width: 75% !important; -} - -tr { - padding: 5% !important; - line-height: 1.2em; - border: 0.5px solid #cccccc; -} - -td { - min-width: 20%; - word-break: break-word; - font-size: 0.9em; - text-align: left; - border: 0.5px solid #cccccc; - padding: 2%; -} - -th { - line-height: 2em; - background-color: #efefef; - text-align: left; - padding: 2%; - border: 0.5px solid #cccccc; - padding: 5% !important; -} - -@keyframes bouncing { - 0% { - bottom: 0; - } - 50% { - bottom: 20px; - } - 100% { - bottom: 0; - } -} - -html { - overflow-x: hidden; -} - -p img { - width: 100%; -} - - -.btn { - margin-top: 2%; - margin-left: 0%; - margin-right: 0%; - margin-bottom: 2%; - color: #116068; - background-color: white; - border: 2px solid #116068; -} - -.btn a { - color: #116068; -} - -.pt-thumbnail { - width: 100% !important; -} - - -.page-item.active .page-link { - background-color: #0CC1C8 !important; - border-color: #0CC1C8; - color: #ffffff !important; -} - -.page-link { - color: #0CC1C8 !important; -} - -.testimonialsection { - vertical-align: top; - float: left; - text-align: center; - width: 33%; - padding-right: 4%; - font-size: 0.8em; - line-height: 1.5em; - color :#333333 !important; - font-style: italic; - padding-top: 2%; -} - - -.testimonialrow { - vertical-align: top; - display: inline-block; - float: left; - width: 100% !Important; - padding-right: 4%; - padding-top: 2%; -} - - -.testimonialsection img { - display: inline-block; - width: 60%; - - padding-bottom: 6%; - vertical-align: top; -} - -.testimonialimage { - margin-bottom: 5%; - padding: 3%; - vertical-align: top; -} - - -.testimonialquote { - float: left; - font-size: 3em; - color: #333333 !important; - font-style: italic; - padding: 2%; -} - -.aboutsection2 { - float: left; -} - -.plus { - color: #333333; - display: inline; - margin-right: 2%; -} - - -.plusmain { - color: #333333; - display: inline; -} - -.pagination { - padding-top: 10%; -} - -.dropdown-item { - font-size: 0.8em; -} - - -.arrow { - animation: bouncing 1s infinite ease-in-out; - bottom: 0; - display: block; - height: 50px; - left: 50%; - margin-left: -25px; - position: absolute; - width: 50px; -} - - - -body { - margin: 0 auto; -} - -.topbanner { - width: 100%; - color: #0CC1C8; - padding-top: 0%; - padding-bottom: 5%; - text-align: center; - font-family: 'Open Sans', sans-serif; - font-weight: 300; - font-size: 1.3em; - background-image: url('../img/graphic-04.svg'); - background-repeat: repeat; - position:relative; - background-size: 100%; - -} - -.topbannersub { - width: 100%; - color: white; - padding-bottom: 2%; - text-align: left; - float: center; - font-family: 'Open Sans', sans-serif; - font-weight: 300; - font-size: 18pt; - background-image: url('../img/graphic-04.svg'); - background-repeat: repeat; - position: relative; - background-size: 100%; -} - - -.topnav { - font-family: 'Open Sans', sans-serif; - font-weight: 400; - font-size: 10pt; - letter-spacing: 0.05em; - margin-right: 5%; - color: white; - text-align: right; - text-transform: uppercase; -} - -.topnav a { - color: #ffffff; -} - -.topnav .dropdown-menu a { - color: #212529; -} - -.logonav { - font-family: 'Open Sans', sans-serif; - font-weight: 400; - font-size: 10pt; - float: left; - position: absolute; - letter-spacing: 0.05em; - margin-left: 5%; - word-spacing: 2em; - color: white; - width: 10%; - z-index: 10; - text-align: left; - text-transform: uppercase; -} - -.logonav img{ - width: 100% !important; -} - -.subnav { - font-family: 'Open Sans', sans-serif; - font-weight: 400; - font-size: 10pt; - letter-spacing: 0.05em; - background-color: #EBF2F2; - color: #505050; - padding-top: 2%; - padding-bottom: 2%; - text-align: center; - text-transform: uppercase; -} - -.subnav a { - color: #606060; -} - -.subnav a:hover { - color: #0CC1C8; - text-decoration: none; -} - -.subnav a:active, .subnav a.active { - color: #0CC1C8; -} - -.subnav.selected a:selected:link, a:selected:active{ - color: #0CC1C8; -} - -.subnav a:focus { - color: #0CC1C8; - font-weight: 700; -} - -.navbar-brand { - padding-top: 0.5em !important; - padding-left: 1.8em !important; -} - -/* -col-md-9 faq-container { - max-width:100% !important; -} -*/ - -.headertext { - font-size: 30pt; - padding-top: 6%; - text-align: center; -} - -.topbannertext{ - width: 35%; - margin-left: 32.5%; - padding-top: 0.5%; - font-size: 1em !important; - padding-bottom: 0.5%; -} - -.bannerlogo { - padding-top: 2%; - float: left; - width: 100%; -} - -.bannerlogosub { - padding-top: 2%; - float: left; - width: 100%; -} - - -.bannerlogo img{ - width: 50%; -} - - -button { - font-family: 'Open Sans', sans-serif; - background-color: white; - color: #116068; - border: 0px solid; - padding-left: 3%; - padding-right: 3%; - font-weight: bold; - padding-top: 1.5%; - padding-bottom: 1.5%; - margin: 2%; - letter-spacing: 0.07em; - font-size: 13pt; - cursor: pointer; -} - -.section2 { - padding-top: 3%; - font-family: 'Open Sans', sans-serif; - width: 82%; - font-weight: 100; - font-size: 1em; - color: #606060; - line-height: 1.7em; - padding-left: 16%; - text-align: center; -} - -.docssection2 { - padding-top:1%; - font-family: 'Open Sans', sans-serif; - width:100%; - font-weight:100; - font-size:1em; - color:#606060; - line-height:1.7em; - padding-left:0%; - text-align:center; -} - - -.section3 { - font-family: 'Open Sans', sans-serif; - width: 100%; - font-weight: 100; - float: left; - margin-bottom: 5%; - background-color: white; - text-align: center; - position: relative; -} - -.refsection { - padding-top: 3%; - padding-bottom: 3%; - font-family: 'Open Sans', sans-serif; - width: 85%; - font-weight: 100; - font-size: 1em; - color: #606060; - line-height: 1.7em; - padding-left: 15%; - text-align: left; -} - -.videosection { - padding-top: 3%; - padding-bottom: 3%; - font-family: 'Open Sans', sans-serif; - width: 80%; - font-weight: 100; - font-size: 1em; - color: #606060; - line-height: 1.7em; - padding-left: 20%; - text-align: left; -} - -.docusecasesection { - font-family: 'Open Sans', sans-serif; - width:100%; - margin-top: 2%; - font-weight: 100; - float: left; -} -.docusecasesection h4 { - font-size: 2.3em !important; - padding-top: 3%; - padding-left: 5%; - padding-right: 5%; -} - -.doclangsection { - font-family: 'Open Sans', sans-serif; - width: 100%; - margin-top: 4%; - font-weight: 100; - background-color: #EBF2F2; - float: left; -} -.doclangsection h4 { - font-size: 2.3em !important; - padding-top: 3%; - padding-left: 5%; - padding-right: 5%; -} - - -.docprojectsection { - font-family: 'Open Sans', sans-serif; - width: 100%; - margin-top: 2%; - font-weight: 100; - background-color: #EBF2F2; - float: left; -} - -.docprojectsection h4 { - font-size: 2.3em !important; - padding-left: 5%; - padding-right: 5%; - padding-top: 3%; -} - -.doccols { - margin-bottom: 3%; - font-family: 'Open Sans', sans-serif; - width: 100%; - padding-top: 1%; - padding-bottom: 4%; - font-weight: 100; - padding-left: 10%; - float: left; -} - -a { - color: #0CC1C8; - font-weight: 400; - text-decoration: none; -} - -.cols { - margin-top: 5%; - margin-bottom: 3%; - font-family: 'Open Sans', sans-serif; - font-size: 0.95em; - color: #505050; - font-weight: 100; - background-color: #EBF2F2; - padding-left: 15%; - padding-top: 2%; - padding-bottom: 1%; - float: left; -} - - -.quickstartcols { - margin-bottom: 17%; - font-family: 'Open Sans', sans-serif; - margin-left: 10%; - width: 100%; - font-weight: 100; - font-size: 11pt; - padding-left: 5%; - float: left; -} - - -.quickstartcol1 { - float: left; - line-height: 1em !important; - display: block; - font-size: 0.9em; - text-align: left; - width: 20%; - margin-right: 0%; - padding: 3%; - padding-top: 5%; -} - - -.quickstartcol2 { - float: left; - text-align: left; - width: 60%; - line-height: 1.6em; - margin-right: 2%; - padding-left: 5%; - border-left: 0.5px solid #cccccc; -} - - -.quickstartcol1 h8{ - font-size: 1.2em; - display: block; - line-height: 1.3em; - margin-bottom: 10%; -} - - -.quickstartcol1 a { - line-height: 1.5em; - margin-bottom: 10%; - margin-top: 4%; - display: block; -} - -.quickstartcol1 .active { - color: #266B6B !important; - font-weight: bold; -} - -.blogcols { - margin-bottom: 17%; - font-family: 'Open Sans', sans-serif; - width: 90%; - margin-left: 8%; - font-weight: 100; - font-size: 1.2em; - padding-left: 8%; - float: left; -} - -.singleblog { - margin-bottom: 10%; - font-family: 'Open Sans', sans-serif; - width: 70%; - margin-left: 15%; - font-weight: 100; - font-size: 11pt; - margin-top: 4%; - float: left; -} - -.blogcol1 { - float: left; - text-align: left; - width: 55%; - line-height: 1.6em; - margin-right: 2%; - padding: 3%; - padding-left: 0px; - padding-right: 3%; - padding-top: 2%; - font-size: 0.8em !important; -} - -.blogcol2 { - float: left; - width: 20%; - text-align: left; - width: 20%; - line-height: 2em; - padding-top: 1%; - font-size: 0.7em; - margin-right: 2%; - padding-left: 3%; - padding-left: 3%; - margin-top: 4%; - border-left: 0.5px solid #cccccc; -} - -.docscol1 a { - padding-bottom: 3% !important; -} - -.docscol2 { - float: left; - width: 28%; - line-height: 1.6em; - margin-right: 5%; - padding-bottom: 3%; -} - -.docscol3 { - float: left; - display: block; - width: 28%; - line-height: 1.6em; - margin-right: 2%; - padding-bottom: 3%; -} - - -.docscol1 { - float: left; - width: 28%; - line-height: 1.6em; - margin-right: 5%; - padding-bottom: 3%; -} - -.docscol2 { - float: left; - width: 28%; - line-height: 1.6em; - margin-right: 5%; - padding-bottom: 3%; -} - -.docscol3 { - float: left; - width: 28%; - line-height: 1.6em; - margin-right: 2%; - padding-bottom: 3%; -} - -.docstext { - font-family: 'Open Sans', sans-serif; - width: 90%; - float: left; - font-size: 12pt; - padding-bottom:1%; - color: #707070; - line-height: 1.5em; - padding-right: 5%; - margin-bottom: 5%; -} - - -.col1 { - float: left; - width: 40%; - text-align: left; - display: block; - padding-right: 2%; - padding-top: 2%; - padding-bottom: 2%; -} - -.col2 { - float: left; - width: 40%; - padding-top: 1%; - padding-bottom: 2%; -} - -.col1image{ - float: left; - display: block; - width: 25%; - margin-right: 5%; - margin-bottom: 10%; - padding: 3%; - display: block; -} - -.col2image{ - float: left; - width: 25%; - margin-right: 5%; - padding: 2%; -} - -.colpart1 { - float: left; - padding-bottom: 2%; -} - -.colpart2 { - float: left; - padding-top: 2%; -} - -.companybox { - margin-left: 15%; - margin-top: 3%; -} - -.companybox img { - position: relative; - margin: 1.15%; - padding: 1%; - width: 8%; - opacity: 0.3; - text-align: enter; - float: left; - display: inline-block; - border: 1px solid grey; - float: left; - background-color: white; -} - - - -.section4 { - font-family: 'Open Sans', sans-serif; - width: 100%; - background-size: 100%; - float: left; - font-size: 14pt; - text-align: center; - background-image: url('../img/graphic-04.svg'); - background-repeat: no-repeat; - position: relative; - background-size: 100%; - padding-bottom: 7%; - padding-left: 5%; - padding-right: 5%; - padding-top: 5%; - font-weight: 100; - color: white; - margin-top: 2%; -} - - -h1 { - font-family: 'Open Sans', sans-serif; - font-size: 2.5em; - color: #0CC1C8; - margin-bottom: 3%; - margin-top: 1%; - font-weight: 300; -} - -h2 { - font-family: 'Open Sans', sans-serif; - font-size: 1.5em; - color: #0CC1C8; - margin-bottom: 3%; - margin-top: 3%; - font-weight: 300; -} - -.lead { - font-size: 1em !important; -} - - -h3 { - font-family: 'Open Sans', sans-serif; - color: #266B6B; - font-weight: 300; - padding-top: 2%; - padding-bottom: 1%; -} - -h4 { - font-family: 'Open Sans', sans-serif; - font-size: 1.5em; - padding-top: 3%; - padding-bottom: 0%; - color: #33838b; - margin-bottom: 3%; - color: #0CC1C8; - font-weight: 300; - margin-top: 3%; -} - -h5 { - font-family: 'Open Sans', sans-serif; - font-size: 9pt; - font-weight: 300; -} - -h6 { - font-size: 1.4em; - font-family: 'Open Sans', sans-serif; - color: #266B6B; - font-weight: 300; - padding-top: 2%; - padding-bottom: 1%; -} - -h8 { - font-size: 2em; - font-family: 'Open Sans', sans-serif; - color: #266B6B; - font-weight: 300; - padding-top: 2%; - padding-bottom: 1%; -} - - -@media screen and (max-width: 1100px) { - table { - margin-top: 4%; - margin-bottom: 4%; - width: 100% !important; - } - - tr { - padding:5% !important; - line-height: 1.2em; - border: 0.5px solid #cccccc; - } - - td { - font-size: 0.9em; - text-align: left; - border: 0.5px solid #cccccc; - padding: 2%; - } - - th { - line-height: 2em; - background-color: #efefef; - text-align: left; - padding: 2%; - border: 0.5px solid #cccccc; - padding: 5% !important; - } - - .refsection { - width: 90%; - padding-left: 10%; - } - - .col1image { - padding-bottom: 0%; - padding-top: 0%; - margin-bottom: 0%; - margin-right: 5%; - width: 20%; - } - - .col1 { - width: 80%; - padding-bottom: 0%; - margin-bottom: 0%; - } - - .col2 { - width: 80%; - padding-bottom: 0%; - margin-bottom: 0%; - } - - .cols { - padding-bottom: 5%; - padding-left: 15%; - } - - .col1 h3 { - font-size: 0.5em !important; - } - - .col2 h3 { - font-size: 0.5em !important; - } - - .section4 { - background-repeat: repeat; - } - - .col1image { - padding-bottom: 3%; - margin-bottom: 0%; - margin-right: 5%; - } - - .colpart1 { - padding-bottom: 0%; - } - - .colpart2 { - padding-top: 0%; - padding-bottom: 0%; - } - - .section2 { - padding-top: 3%; - font-family: 'Open Sans', sans-serif; - width: 90%; - font-weight: 100; - font-size: 1em; - color: #606060; - line-height: 1.7em; - padding-left: 10%; - text-align: center; - } - - .bannerlogo img { - width: 35% !important; - } -} - -@media screen and (max-width: 900px) { - .topbanner { - width: 100%; - background-image: url('../img/graphic-04-mobile.svg'); - } - - .topbannersub { - width: 100%; - background-image: url('../img/graphic-04-mobile.svg'); - background-repeat: repeat; - position: relative; - background-size: 100%; - } - - .bannerlogo img { - width:60% !important; - } - - .topbannertext { - width: 70% !important; - margin-left: 15% !important; - padding-top: 2%; - font-size: 1em !important; - padding-bottom: 0% !important; - } - - .singleblog { - margin-bottom: 10%; - font-family: 'Open Sans', sans-serif; - width: 90%; - margin-left: 5%; - font-weight: 100; - font-size: 11pt; - margin-top: 4%; - float: left; - } - - .blogcols { - margin-bottom: 17%; - font-family: 'Open Sans', sans-serif; - width: 100%; - margin-left: 2%; - font-weight: 100; - font-size: 0.8em; - float: left; - } - - .blogcol1 { - float: left; - text-align: left; - width: 90%; - line-height: 1.6em; - margin-right: 2%; - padding: 3%; - padding-right: 3%; - padding-top: 2%; - font-size: 0.8em; - } - - .col1image { - padding-bottom: 3%; - margin-bottom: 5%; - margin-right: 5%; - } - - h2 { - font-size: 1.5em !important; - padding-top: 2%; - padding-bottom: 2%; - } - - .quickstartcols { - margin-bottom: 17%; - font-family: 'Open Sans', sans-serif; - width: 100% !important; - margin-left: 4%; - font-weight: 100; - font-size: 11pt; - padding-left: 5%; - float: left; - } - - .quickstartcols img { - width: 100% !important; - } - - .quickstartcol2 h3 { - font-size: 2.3em !important; - } - - .quickstartcol2 h1 { - font-size: 2em !important; - } - - .blogcol2 { - display: none; - } - - .quickstartcol1 { - float: left; - text-align: left; - width: 25%; - line-height: 2em; - padding: 0%; - margin-right: 3%; - padding-right: 0%; - padding-top: 5%; - } - - .quickstartcol2 { - float: left; - text-align: left; - width: 60%; - line-height: 1.6em; - margin-right: 2%; - padding-left: 2%; - padding-left: 4%; - border-left: 0.5px solid #cccccc; - } -} - - -@media screen and (max-width: 700px) { - .headertext { - padding-top: 15%; - } - - .subnav { - font-size: 1em; - padding-top: 3%; - padding-bottom: 3%; - padding-left: 2%; - padding-right: 2%; - } - - .docscol1 { - float: left; - width: 90%; - line-height: 2em; - margin-right: 2%; - padding-bottom: 3%; - text-align: center; - } - - .docscol2 { - float: left; - width: 90% !important; - line-height: 2em; - margin-right: 2%; - padding-bottom: 3%; - text-align: center; - } - - .docscol3 { - float: left; - width: 90%; - line-height: 2em; - margin-right: 2%; - padding-bottom: 3%; - text-align: center; - } - - .doccols { - margin-bottom: 3%; - margin-top: 0%; - font-family: 'Open Sans', sans-serif; - width: 100%; - padding-top: 6%; - padding-bottom: 4%; - font-weight: 100; - background-color: #EBF2F2; - padding-left: 5%; - float: left; - } - - .docstext { - width: 95%; - font-size: 0.9em; - padding-left: 5%; - padding-bottom: 5%; - text-align: center; - } - - .dropdown-menu { - opacity: 0.9; - float: right !important; - width: 50%; - } - - .topbannertext { - margin-bottom: 5%; - width: 80%; - margin-left: 10%; - font-size: 1em; - } - - .section4 { - background-image: url('../img/graphic-04-mobile.svg'); - } - - .button { - padding-bottom: 5%; - } - - .col1 { - width: 90%; - } - - .col2 { - width: 90%; - } - - .cols { - padding-bottom: 8%; - } - - .section4 { - background-repeat: repeat; - } - - .col1image { - margin-right: 5%; - margin-bottom: 10% !important; - } - - h2 { - font-size: 1.5em; - padding-top: 4%; - padding-bottom: 4%; - } - - h1 { - font-size:2.2em; - padding-top:4%; - padding-bottom:4%; - } - - .companybox img { - width:20%; - } - - .section2 { - padding-bottom:4%; - } - - .section3 { - width:100%; - margin-bottom:7%; - } - - button { - font-family: 'Open Sans', sans-serif; - background-color: white; - color: #116068; - border: 0px solid; - padding-left: 4%; - padding-right: 4%; - font-weight: bold; - padding-top: 3%; - padding-bottom: 3%; - margin: 1%; - margin-bottom: 10%; - letter-spacing: 0.07em; - font-size: 13pt; - } - - .colpart1 { - padding-bottom: 5%; - text-align: left; - } - - .colpart2 { - padding-top: 0%; - padding-bottom: 0%; - } - - .coltext1 { - text-align: left; - display: block; - } - - .cols { - padding-bottom: 14%; - padding-top: 5%; - font-size: 0.9em !important; - padding-left: 8%; - } - - h3 { - font-size: 1.8em; - } - - .companybox { - margin-left: 10%; - } - - .videosection { - padding-top: 3%; - padding-bottom: 3%; - font-family: 'Open Sans', sans-serif; - width: 90%; - font-weight: 100; - font-size: 1em; - color: #606060; - line-height: 1.7em; - padding-left: 10%; - text-align: left; - } -} - -@media screen and (max-width:450px){ - .col1image { - padding-bottom: 5%; - margin-bottom: 20% !important; - margin-right: 3%; - width: 30%; - display: block; - } -} diff --git a/public/docs/guides/auth.html b/public/docs/guides/auth.html deleted file mode 100644 index 00d0c51..0000000 --- a/public/docs/guides/auth.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/guides/auth/ \ No newline at end of file diff --git a/public/docs/guides/auth/index.html b/public/docs/guides/auth/index.html deleted file mode 100644 index b333c74..0000000 --- a/public/docs/guides/auth/index.html +++ /dev/null @@ -1,689 +0,0 @@ - - - - - - - - - - - -Authentication – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- - - -
-

- Authentication -

- - - -

This document provides an overview of gRPC authentication, -including our built-in supported auth mechanisms, how to plug in your own -authentication systems, and examples of how to use gRPC auth in our supported -languages.

- -
- -

Overview

- -

gRPC is designed to work with a variety of authentication mechanisms, making it -easy to safely use gRPC to talk to other systems. You can use our supported -mechanisms - SSL/TLS with or without Google token-based authentication - or you -can plug in your own authentication system by extending our provided code.

- -

gRPC also provides a simple authentication API that lets you provide all the -necessary authentication information as Credentials when creating a channel or -making a call.

- -

Supported auth mechanisms

- -

The following authentication mechanisms are built-in to gRPC:

- -
    -
  • SSL/TLS: gRPC has SSL/TLS integration and promotes the use of SSL/TLS -to authenticate the server, and to encrypt all the data exchanged between -the client and the server. Optional mechanisms are available for clients to -provide certificates for mutual authentication.
  • -
  • Token-based authentication with Google: gRPC provides a generic -mechanism (described below) to attach metadata based credentials to requests -and responses. Additional support for acquiring access tokens -(typically OAuth2 tokens) while accessing Google APIs through gRPC is -provided for certain auth flows: you can see how this works in our code -examples below. In general this mechanism must be used as well as SSL/TLS -on the channel - Google will not allow connections without SSL/TLS, and -most gRPC language implementations will not let you send credentials on an -unencrypted channel.
  • -
- -

WARNING: Google credentials should only -be used to connect to Google services. Sending a Google issued OAuth2 token -to a non-Google service could result in this token being stolen and used to -impersonate the client to Google services.

- -

Authentication API

- -

gRPC provides a simple authentication API based around the unified concept of -Credentials objects, which can be used when creating an entire gRPC channel or -an individual call.

- -

Credential types

- -

Credentials can be of two types:

- -
    -
  • Channel credentials, which are attached to a Channel, such as SSL -credentials.
  • -
  • Call credentials, which are attached to a call (or ClientContext in -C++).
  • -
- -

You can also combine these in aCompositeChannelCredentials, allowing you to -specify, for example, SSL details for the channel along with call credentials -for each call made on the channel. A CompositeChannelCredentials associates a -ChannelCredentials and a CallCredentials to create a new -ChannelCredentials. The result will send the authentication data associated -with the composed CallCredentialswith every call made on the channel.

- -

For example, you could create a ChannelCredentials from an SslCredentials -and an AccessTokenCredentials. The result when applied to a Channel would -send the appropriate access token for each call on this channel.

- -

Individual CallCredentials can also be composed using -CompositeCallCredentials. The resulting CallCredentials when used in a call -will trigger the sending of the authentication data associated with the two -CallCredentials.

- -

Using client-side SSL/TLS

- -

Now let’s look at how Credentials work with one of our supported auth -mechanisms. This is the simplest authentication scenario, where a client just -wants to authenticate the server and encrypt all data. The example is in C++, -but the API is similar for all languages: you can see how to enable SSL/TLS in -more languages in our Examples section below.

-
// Create a default SSL ChannelCredentials object.
-auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
-// Create a channel using the credentials created in the previous step.
-auto channel = grpc::CreateChannel(server_name, channel_creds);
-// Create a stub on the channel.
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-// Make actual RPC calls on the stub.
-grpc::Status s = stub->sayHello(&context, *request, response);
-
-

For advanced use cases such as modifying the root CA or using client certs, -the corresponding options can be set in the SslCredentialsOptions parameter -passed to the factory method.

- -

Using Google token-based authentication

- -

gRPC applications can use a simple API to create a credential that works for -authentication with Google in various deployment scenarios. Again, our example -is in C++ but you can find examples in other languages in our Examples section.

-
auto creds = grpc::GoogleDefaultCredentials();
-// Create a channel, stub and make RPC calls (same as in the previous example)
-auto channel = grpc::CreateChannel(server_name, creds);
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-grpc::Status s = stub->sayHello(&context, *request, response);
-
-

This channel credentials object works for applications using Service Accounts as -well as for applications running in Google Compute Engine -(GCE). In the former case, the service -account’s private keys are loaded from the file named in the environment -variable GOOGLE_APPLICATION_CREDENTIALS. The keys are used to generate bearer -tokens that are attached to each outgoing RPC on the corresponding channel.

- -

For applications running in GCE, a default service account and corresponding -OAuth2 scopes can be configured during VM setup. At run-time, this credential -handles communication with the authentication systems to obtain OAuth2 access -tokens and attaches them to each outgoing RPC on the corresponding channel.

- -

Extending gRPC to support other authentication mechanisms

- -

The Credentials plugin API allows developers to plug in their own type of -credentials. This consists of:

- -
    -
  • The MetadataCredentialsPlugin abstract class, which contains the pure virtual -GetMetadata method that needs to be implemented by a sub-class created by -the developer.
  • -
  • The MetadataCredentialsFromPlugin function, which creates a CallCredentials -from the MetadataCredentialsPlugin.
  • -
- -

Here is example of a simple credentials plugin which sets an authentication -ticket in a custom header.

-
class MyCustomAuthenticator : public grpc::MetadataCredentialsPlugin {
- public:
-  MyCustomAuthenticator(const grpc::string& ticket) : ticket_(ticket) {}
-
-  grpc::Status GetMetadata(
-      grpc::string_ref service_url, grpc::string_ref method_name,
-      const grpc::AuthContext& channel_auth_context,
-      std::multimap<grpc::string, grpc::string>* metadata) override {
-    metadata->insert(std::make_pair("x-custom-auth-ticket", ticket_));
-    return grpc::Status::OK;
-  }
-
- private:
-  grpc::string ticket_;
-};
-
-auto call_creds = grpc::MetadataCredentialsFromPlugin(
-    std::unique_ptr<grpc::MetadataCredentialsPlugin>(
-        new MyCustomAuthenticator("super-secret-ticket")));
-
-

A deeper integration can be achieved by plugging in a gRPC credentials -implementation at the core level. gRPC internals also allow switching out -SSL/TLS with other encryption mechanisms.

- -

Examples

- -

These authentication mechanisms will be available in all gRPC’s supported -languages. The following sections demonstrate how authentication and -authorization features described above appear in each language: more languages -are coming soon.

- -

Go

- -
Base case - no encryption or authentication
- -

Client:

-
conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
-// error handling omitted
-client := pb.NewGreeterClient(conn)
-// ...
-

Server:

-
s := grpc.NewServer()
-lis, _ := net.Listen("tcp", "localhost:50051")
-// error handling omitted
-s.Serve(lis)
-
With server authentication SSL/TLS
- -

Client:

-
creds, _ := credentials.NewClientTLSFromFile(certFile, "")
-conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds))
-// error handling omitted
-client := pb.NewGreeterClient(conn)
-// ...
-

Server:

-
creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile)
-s := grpc.NewServer(grpc.Creds(creds))
-lis, _ := net.Listen("tcp", "localhost:50051")
-// error handling omitted
-s.Serve(lis)
-
Authenticate with Google
-
pool, _ := x509.SystemCertPool()
-// error handling omitted
-creds := credentials.NewClientTLSFromCert(pool, "")
-perRPC, _ := oauth.NewServiceAccountFromFile("service-account.json", scope)
-conn, _ := grpc.Dial(
-	"greeter.googleapis.com",
-	grpc.WithTransportCredentials(creds),
-	grpc.WithPerRPCCredentials(perRPC),
-)
-// error handling omitted
-client := pb.NewGreeterClient(conn)
-// ...
-

Ruby

- -
Base case - no encryption or authentication
-
stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
-...
-
With server authentication SSL/TLS
-
creds = GRPC::Core::Credentials.new(load_certs)  # load_certs typically loads a CA roots file
-stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)
-
Authenticate with Google
-
require 'googleauth'  # from http://www.rubydoc.info/gems/googleauth/0.1.0
-...
-ssl_creds = GRPC::Core::ChannelCredentials.new(load_certs)  # load_certs typically loads a CA roots file
-authentication = Google::Auth.get_application_default()
-call_creds = GRPC::Core::CallCredentials.new(authentication.updater_proc)
-combined_creds = ssl_creds.compose(call_creds)
-stub = Helloworld::Greeter::Stub.new('greeter.googleapis.com', combined_creds)
-

C++

- -
Base case - no encryption or authentication
-
auto channel = grpc::CreateChannel("localhost:50051", InsecureChannelCredentials());
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-...
-
-
With server authentication SSL/TLS
-
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
-auto channel = grpc::CreateChannel("myservice.example.com", channel_creds);
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-...
-
-
Authenticate with Google
-
auto creds = grpc::GoogleDefaultCredentials();
-auto channel = grpc::CreateChannel("greeter.googleapis.com", creds);
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-...
-
-

C#

- -
Base case - no encryption or authentication
-
var channel = new Channel("localhost:50051", ChannelCredentials.Insecure);
-var client = new Greeter.GreeterClient(channel);
-...
-
-
With server authentication SSL/TLS
-
var channelCredentials = new SslCredentials(File.ReadAllText("roots.pem"));  // Load a custom roots file.
-var channel = new Channel("myservice.example.com", channelCredentials);
-var client = new Greeter.GreeterClient(channel);
-
-
Authenticate with Google
-
using Grpc.Auth;  // from Grpc.Auth NuGet package
-...
-// Loads Google Application Default Credentials with publicly trusted roots.
-var channelCredentials = await GoogleGrpcCredentials.GetApplicationDefaultAsync();
-
-var channel = new Channel("greeter.googleapis.com", channelCredentials);
-var client = new Greeter.GreeterClient(channel);
-...
-
-
Authenticate a single RPC call
-
var channel = new Channel("greeter.googleapis.com", new SslCredentials());  // Use publicly trusted roots.
-var client = new Greeter.GreeterClient(channel);
-...
-var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
-var result = client.SayHello(request, new CallOptions(credentials: googleCredential.ToCallCredentials()));
-...
-
-

Python

- -
Base case - No encryption or authentication
-
import grpc
-import helloworld_pb2
-
-channel = grpc.insecure_channel('localhost:50051')
-stub = helloworld_pb2.GreeterStub(channel)
-
With server authentication SSL/TLS
- -

Client:

-
import grpc
-import helloworld_pb2
-
-with open('roots.pem', 'rb') as f:
-    creds = grpc.ssl_channel_credentials(f.read())
-channel = grpc.secure_channel('myservice.example.com:443', creds)
-stub = helloworld_pb2.GreeterStub(channel)
-

Server:

-
import grpc
-import helloworld_pb2
-from concurrent import futures
-
-server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-with open('key.pem', 'rb') as f:
-    private_key = f.read()
-with open('chain.pem', 'rb') as f:
-    certificate_chain = f.read()
-server_credentials = grpc.ssl_server_credentials( ( (private_key, certificate_chain), ) )
-# Adding GreeterServicer to server omitted
-server.add_secure_port('myservice.example.com:443', server_credentials)
-server.start()
-# Server sleep omitted
-
Authenticate with Google using a JWT
-
import grpc
-import helloworld_pb2
-
-from google import auth as google_auth
-from google.auth import jwt as google_auth_jwt
-from google.auth.transport import grpc as google_auth_transport_grpc
-
-credentials, _ = google_auth.default()
-jwt_creds = google_auth_jwt.OnDemandCredentials.from_signing_credentials(
-    credentials)
-channel = google_auth_transport_grpc.secure_authorized_channel(
-    jwt_creds, None, 'greeter.googleapis.com:443')
-stub = helloworld_pb2.GreeterStub(channel)
-
Authenticate with Google using an Oauth2 token
-
import grpc
-import helloworld_pb2
-
-from google import auth as google_auth
-from google.auth.transport import grpc as google_auth_transport_grpc
-from google.auth.transport import requests as google_auth_transport_requests
-
-credentials, _ = google_auth.default(scopes=(scope,))
-request = google_auth_transport_requests.Request()
-channel = google_auth_transport_grpc.secure_authorized_channel(
-    credentials, request, 'greeter.googleapis.com:443')
-stub = helloworld_pb2.GreeterStub(channel)
-

Java

- -
Base case - no encryption or authentication
-
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
-    .usePlaintext(true)
-    .build();
-GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
-
With server authentication SSL/TLS
- -

In Java we recommend that you use OpenSSL when using gRPC over TLS. You can find -details about installing and using OpenSSL and other required libraries for both -Android and non-Android Java in the gRPC Java -Security -documentation.

- -

To enable TLS on a server, a certificate chain and private key need to be -specified in PEM format. Such private key should not be using a password. -The order of certificates in the chain matters: more specifically, the certificate -at the top has to be the host CA, while the one at the very bottom -has to be the root CA. The standard TLS port is 443, but we use 8443 below to -avoid needing extra permissions from the OS.

-
Server server = ServerBuilder.forPort(8443)
-    // Enable TLS
-    .useTransportSecurity(certChainFile, privateKeyFile)
-    .addService(TestServiceGrpc.bindService(serviceImplementation))
-    .build();
-server.start();
-

If the issuing certificate authority is not known to the client then a properly -configured SslContext or SSLSocketFactory should be provided to the -NettyChannelBuilder or OkHttpChannelBuilder, respectively.

- -

On the client side, server authentication with SSL/TLS looks like this:

-
// With server authentication SSL/TLS
-ManagedChannel channel = ManagedChannelBuilder.forAddress("myservice.example.com", 443)
-    .build();
-GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
-
-// With server authentication SSL/TLS; custom CA root certificates; not on Android
-ManagedChannel channel = NettyChannelBuilder.forAddress("myservice.example.com", 443)
-    .sslContext(GrpcSslContexts.forClient().trustManager(new File("roots.pem")).build())
-    .build();
-GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
-
Authenticate with Google
- -

The following code snippet shows how you can call the Google Cloud PubSub -API using gRPC with a service -account. The credentials are loaded from a key stored in a well-known location -or by detecting that the application is running in an environment that can -provide one automatically, e.g. Google Compute Engine. While this example is -specific to Google and its services, similar patterns can be followed for other -service providers.

-
GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
-ManagedChannel channel = ManagedChannelBuilder.forTarget("greeter.googleapis.com")
-    .build();
-GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel)
-    .withCallCredentials(MoreCallCredentials.from(creds));
-

Node.js

- -
Base case - No encryption/authentication
-
var stub = new helloworld.Greeter('localhost:50051', grpc.credentials.createInsecure());
-
-
With server authentication SSL/TLS
-
var ssl_creds = grpc.credentials.createSsl(root_certs);
-var stub = new helloworld.Greeter('myservice.example.com', ssl_creds);
-
-
Authenticate with Google
-
// Authenticating with Google
-var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
-...
-var ssl_creds = grpc.credentials.createSsl(root_certs);
-(new GoogleAuth()).getApplicationDefault(function(err, auth) {
-  var call_creds = grpc.credentials.createFromGoogleCredential(auth);
-  var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds);
-  var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials);
-});
-
-
Authenticate with Google using Oauth2 token (legacy approach)
-
var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
-...
-var ssl_creds = grpc.Credentials.createSsl(root_certs); // load_certs typically loads a CA roots file
-var scope = 'https://www.googleapis.com/auth/grpc-testing';
-(new GoogleAuth()).getApplicationDefault(function(err, auth) {
-  if (auth.createScopeRequired()) {
-    auth = auth.createScoped(scope);
-  }
-  var call_creds = grpc.credentials.createFromGoogleCredential(auth);
-  var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds);
-  var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials);
-});
-
-

PHP

- -
Base case - No encryption/authorization
-
$client = new helloworld\GreeterClient('localhost:50051', [
-    'credentials' => Grpc\ChannelCredentials::createInsecure(),
-]);
-...
-
Authenticate with Google
-
function updateAuthMetadataCallback($context)
-{
-    $auth_credentials = ApplicationDefaultCredentials::getCredentials();
-    return $auth_credentials->updateMetadata($metadata = [], $context->service_url);
-}
-$channel_credentials = Grpc\ChannelCredentials::createComposite(
-    Grpc\ChannelCredentials::createSsl(file_get_contents('roots.pem')),
-    Grpc\CallCredentials::createFromPlugin('updateAuthMetadataCallback')
-);
-$opts = [
-  'credentials' => $channel_credentials
-];
-$client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);
-````
-
-##### Authenticate with Google using Oauth2 token (legacy approach)
-
-```php
-// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set
-$scope = "https://www.googleapis.com/auth/grpc-testing";
-$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope);
-$opts = [
-  'credentials' => Grpc\Credentials::createSsl(file_get_contents('roots.pem'));
-  'update_metadata' => $auth->getUpdateMetadataFunc(),
-];
-$client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);
-

Dart

- -
Base case - no encryption or authentication
-
final channel = new ClientChannel('localhost',
-      port: 50051,
-      options: const ChannelOptions(
-          credentials: const ChannelCredentials.insecure()));
-final stub = new GreeterClient(channel);
-
With server authentication SSL/TLS
-
// Load a custom roots file.
-final trustedRoot = new File('roots.pem').readAsBytesSync();
-final channelCredentials =
-    new ChannelCredentials.secure(certificates: trustedRoot);
-final channelOptions = new ChannelOptions(credentials: channelCredentials);
-final channel = new ClientChannel('myservice.example.com',
-    options: channelOptions);
-final client = new GreeterClient(channel);
-
Authenticate with Google
-
// Uses publicly trusted roots by default.
-final channel = new ClientChannel('greeter.googleapis.com');
-final serviceAccountJson =
-     new File('service-account.json').readAsStringSync();
-final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson);
-final client =
-    new GreeterClient(channel, options: credentials.toCallOptions);
-
Authenticate a single RPC call
-
// Uses publicly trusted roots by default.
-final channel = new ClientChannel('greeter.googleapis.com');
-final client = new GreeterClient(channel);
-...
-final serviceAccountJson =
-     new File('service-account.json').readAsStringSync();
-final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson);
-final response =
-    await client.sayHello(request, options: credentials.toCallOptions);
-
-
- -
- - - - - - - - - - diff --git a/public/docs/guides/benchmarking.html b/public/docs/guides/benchmarking.html deleted file mode 100644 index 8b32dcc..0000000 --- a/public/docs/guides/benchmarking.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/guides/benchmarking/ \ No newline at end of file diff --git a/public/docs/guides/benchmarking/index.html b/public/docs/guides/benchmarking/index.html deleted file mode 100644 index 07cd396..0000000 --- a/public/docs/guides/benchmarking/index.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - - - - - - -Benchmarking – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- - - -
-

- Benchmarking -

- - - -

gRPC is designed to support high-performance -open-source RPCs in many languages. This document describes the -performance benchmarking tools, the scenarios considered by the tests, -and the testing infrastructure.

- -
- -

- -

Overview

- -

gRPC is designed for both high-performance and high-productivity -design of distributed applications. Continuous performance -benchmarking is a critical part of the gRPC development -workflow. Multi-language performance tests run hourly against -the master branch, and these numbers are reported to a dashboard for -visualization.

- - - -

Additional benchmarking provides fine grained insights into where -CPU is spent.

- - - -

Performance testing design

- -

Each language implements a performance testing worker that implements -a gRPC -WorkerService. This -service directs the worker to act as either a client or a server for -the actual benchmark test, represented as -BenchmarkService. That -service has two methods:

- -
    -
  • UnaryCall - a unary RPC of a simple request that specifies the number of bytes to return in the response
  • -
  • StreamingCall - a streaming RPC that allows repeated ping-pongs of request and response messages akin to the UnaryCall
  • -
- -

gRPC performance testing worker diagram

- -

These workers are controlled by a -driver -that takes as input a scenario description (in JSON format) and an -environment variable specifying the host:port of each worker process.

- -

- -

Languages under test

- -

The following languages have continuous performance testing as both -clients and servers at master:

- -
    -
  • C++
  • -
  • Java
  • -
  • Go
  • -
  • C#
  • -
  • node.js
  • -
  • Python
  • -
  • Ruby
  • -
- -

Additionally, all languages derived from C core have limited -performance testing (smoke testing) conducted at every pull request.

- -

In addition to running as both the client-side and server-side of -performance tests, all languages are tested as clients against a C++ -server, and as servers against a C++ client. This test aims to provide -the current upper bound of performance for a given language’s client or -server implementation without testing the other side.

- -

Although PHP or mobile environments do not support a gRPC server -(which is needed for our performance tests), their client-side -performance can be benchmarked using a proxy WorkerService written in -another language. This code is implemented for PHP but is not yet in -continuous testing mode.

- -

- -

Scenarios under test

- -

There are several important scenarios under test and displayed in the dashboards -above, including the following:

- -
    -
  • Contentionless latency - the median and tail response latencies seen with only 1 client sending a single message at a time using StreamingCall
  • -
  • QPS - the messages/second rate when there are 2 clients and a total of 64 channels, each of which has 100 outstanding messages at a time sent using StreamingCall
  • -
  • Scalability (for selected languages) - the number of messages/second per server core
  • -
- -

Most performance testing is using secure communication and -protobufs. Some C++ tests additionally use insecure communication and -the generic (non-protobuf) API to display peak performance. Additional -scenarios may be added in the future.

- -

- -

Testing infrastructure

- -

All performance benchmarks are run as instances in GCE through our -Jenkins testing infrastructure. In addition to the gRPC performance -scenarios described above, we also run baseline netperf -TCP_RR latency numbers in order to understand -the underlying network characteristics. These numbers are present on -our dashboard and sometimes vary depending on where our instances -happen to be allocated within GCE.

- -

Most test instances are 8-core systems, and these are used for both -latency and QPS measurement. For C++ and Java, we additionally support -QPS testing on 32-core systems. All QPS tests use 2 identical client machines -for each server, to make sure that QPS measurement is not client-limited.

- -
-
- -
- - - - - - - - - - diff --git a/public/docs/guides/concepts.html b/public/docs/guides/concepts.html deleted file mode 100644 index 7871145..0000000 --- a/public/docs/guides/concepts.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/guides/concepts/ \ No newline at end of file diff --git a/public/docs/guides/concepts/index.html b/public/docs/guides/concepts/index.html deleted file mode 100644 index ef78ef6..0000000 --- a/public/docs/guides/concepts/index.html +++ /dev/null @@ -1,409 +0,0 @@ - - - - - - - - - - - -gRPC Concepts – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- -
- -Guides - - - - What is gRPC? - - - - - gRPC Concepts - - - - - Authentication - - - - - Error handling and debugging - - - - - Benchmarking - - - - - gRPC Wire Format - - - -Related Guides - Protocol Buffers -
- -
-

- gRPC Concepts -

- - - -

This document introduces some key gRPC concepts with an overview -of gRPC's architecture and RPC life cycle.

- -

It assumes that you’ve read What is gRPC?. For -language-specific details, see the Quick Start, tutorial, and reference -documentation for your chosen language(s), where available (complete reference -docs are coming soon).

- -
- -

Overview

- -

Service definition

- -

Like many RPC systems, gRPC is based around the idea of defining a service, -specifying the methods that can be called remotely with their parameters and -return types. By default, gRPC uses protocol -buffers as the Interface -Definition Language (IDL) for describing both the service interface and the -structure of the payload messages. It is possible to use other alternatives if -desired.

-
service HelloService {
-  rpc SayHello (HelloRequest) returns (HelloResponse);
-}
-
-message HelloRequest {
-  string greeting = 1;
-}
-
-message HelloResponse {
-  string reply = 1;
-}
-

gRPC lets you define four kinds of service method:

- - -
rpc SayHello(HelloRequest) returns (HelloResponse){
-}
- -
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
-}
- -
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
-}
- -
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
-}
-

We’ll look at the different types of RPC in more detail in the RPC life cycle section below.

- -

Using the API surface

- -

Starting from a service definition in a .proto file, gRPC provides protocol -buffer compiler plugins that generate client- and server-side code. gRPC users -typically call these APIs on the client side and implement the corresponding API -on the server side.

- - - -

Synchronous vs. asynchronous

- -

Synchronous RPC calls that block until a response arrives from the server are -the closest approximation to the abstraction of a procedure call that RPC -aspires to. On the other hand, networks are inherently asynchronous and in many -scenarios it’s useful to be able to start RPCs without blocking the current -thread.

- -

The gRPC programming surface in most languages comes in both synchronous and -asynchronous flavors. You can find out more in each language’s tutorial and -reference documentation (complete reference docs are coming soon).

- -

RPC life cycle

- -

Now let’s take a closer look at what happens when a gRPC client calls a gRPC -server method. We won’t look at implementation details, you can find out more -about these in our language-specific pages.

- -

Unary RPC

- -

First let’s look at the simplest type of RPC, where the client sends a single request and gets back a single response.

- - - -

Server streaming RPC

- -

A server-streaming RPC is similar to our simple example, except the server sends -back a stream of responses after getting the client’s request message. After -sending back all its responses, the server’s status details (status code and -optional status message) and optional trailing metadata are sent back to -complete on the server side. The client completes once it has all the server’s -responses.

- -

Client streaming RPC

- -

A client-streaming RPC is also similar to our simple example, except the client -sends a stream of requests to the server instead of a single request. The server -sends back a single response, typically but not necessarily after it has -received all the client’s requests, along with its status details and optional -trailing metadata.

- -

Bidirectional streaming RPC

- -

In a bidirectional streaming RPC, again the call is initiated by the client -calling the method and the server receiving the client metadata, method name, -and deadline. Again the server can choose to send back its initial metadata or -wait for the client to start sending requests.

- -

What happens next depends on the application, as the client and server can read -and write in any order - the streams operate completely independently. So, for -example, the server could wait until it has received all the client’s messages -before writing its responses, or the server and client could “ping-pong”: the -server gets a request, then sends back a response, then the client sends another -request based on the response, and so on.

- -

- -

Deadlines/Timeouts

- -

gRPC allows clients to specify how long they are willing to wait for an RPC to -complete before the RPC is terminated with the error DEADLINE_EXCEEDED. On -the server side, the server can query to see if a particular RPC has timed out, -or how much time is left to complete the RPC.

- -

How the deadline or timeout is specified varies from language to language - for -example, not all languages have a default deadline, some language APIs work in -terms of a deadline (a fixed point in time), and some language APIs work in -terms of timeouts (durations of time).

- -

RPC termination

- -

In gRPC, both the client and server make independent and local determinations of -the success of the call, and their conclusions may not match. This means that, -for example, you could have an RPC that finishes successfully on the server side -(“I have sent all my responses!”) but fails on the client side (“The responses -arrived after my deadline!“). It’s also possible for a server to decide to -complete before a client has sent all its requests.

- -

Cancelling RPCs

- -

Either the client or the server can cancel an RPC at any time. A cancellation -terminates the RPC immediately so that no further work is done. It is not an -“undo”: changes made before the cancellation will not be rolled back.

- -

- -

Metadata

- -

Metadata is information about a particular RPC call (such as authentication details) in the -form of a list of key-value pairs, where the keys are strings and the values are -typically strings (but can be binary data). Metadata is opaque to gRPC itself - -it lets the client provide information associated with the call to the server -and vice versa.

- -

Access to metadata is language-dependent.

- -

Channels

- -

A gRPC channel provides a connection to a gRPC server on a specified host and -port and is used when creating a client stub (or just “client” in some -languages). Clients can specify channel arguments to modify gRPC’s default -behaviour, such as switching on and off message compression. A channel has -state, including connected and idle.

- -

How gRPC deals with closing down channels is language-dependent. Some languages -also permit querying channel state.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/guides/contributing/index.html b/public/docs/guides/contributing/index.html deleted file mode 100644 index 7d15f0d..0000000 --- a/public/docs/guides/contributing/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - -Contribution Guidelines – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- -
- -Guides - - - - What is gRPC? - - - - - gRPC Concepts - - - - - Authentication - - - - - Error handling and debugging - - - - - Benchmarking - - - - - gRPC Wire Format - - - -Related Guides - Protocol Buffers -
- -
-

- Contribution Guidelines -

- - - -

Contribution Guidelines

- -

Coming soon!

- -
-
- - - - - - - - - - - - diff --git a/public/docs/guides/error.html b/public/docs/guides/error.html deleted file mode 100644 index 4490d71..0000000 --- a/public/docs/guides/error.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/guides/error/ \ No newline at end of file diff --git a/public/docs/guides/error/index.html b/public/docs/guides/error/index.html deleted file mode 100644 index d468046..0000000 --- a/public/docs/guides/error/index.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - - - - - - - - -Error Handling – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- -
- -Guides - - - - What is gRPC? - - - - - gRPC Concepts - - - - - Authentication - - - - - Error handling and debugging - - - - - Benchmarking - - - - - gRPC Wire Format - - - -Related Guides - Protocol Buffers -
- -
-

- Error Handling -

- - - -

This page describes how gRPC deals with errors, including gRPC's built-in error codes. Example code in different languages can be found here.

- -
- -

Error model

- -

As you’ll have seen in our concepts document and examples, when a gRPC call -completes successfully the server returns an OK status to the client -(depending on the language the OK status may or may not be directly used in -your code). But what happens if the call isn’t successful?

- -

If an error occurs, gRPC returns one of its error status codes instead, with an -optional string error message that provides further details about what happened. -Error information is available to gRPC clients in all supported languages.

- -

Error status codes

- -

Errors are raised by gRPC under various circumstances, from network failures to -unauthenticated connections, each of which is associated with a particular -status code. The following error status codes are supported in all gRPC -languages.

- -

General errors

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CaseStatus code
Client application cancelled the requestGRPC_STATUS_CANCELLED
Deadline expired before server returned statusGRPC_STATUS_DEADLINE_EXCEEDED
Method not found on serverGRPC_STATUS_UNIMPLEMENTED
Server shutting downGRPC_STATUS_UNAVAILABLE
Server threw an exception (or did something other than returning a status code to terminate the RPC)GRPC_STATUS_UNKNOWN
- -


- -

Network failures

- - - - - - - - - - - - - - - - - - - - -
CaseStatus code
No data transmitted before deadline expires. Also applies to cases where some data is transmitted and no other failures are detected before the deadline expiresGRPC_STATUS_DEADLINE_EXCEEDED
Some data transmitted (for example, the request metadata has been written to the TCP connection) before the connection breaksGRPC_STATUS_UNAVAILABLE
- -


- -

Protocol errors

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CaseStatus code
Could not decompress but compression algorithm supportedGRPC_STATUS_INTERNAL
Compression mechanism used by client not supported by the serverGRPC_STATUS_UNIMPLEMENTED
Flow-control resource limits reachedGRPC_STATUS_RESOURCE_EXHAUSTED
Flow-control protocol violationGRPC_STATUS_INTERNAL
Error parsing returned statusGRPC_STATUS_UNKNOWN
Unauthenticated: credentials failed to get metadataGRPC_STATUS_UNAUTHENTICATED
Invalid host set in authority metadataGRPC_STATUS_UNAUTHENTICATED
Error parsing response protocol bufferGRPC_STATUS_INTERNAL
Error parsing request protocol bufferGRPC_STATUS_INTERNAL
- -
-
- - - - - - - - - - - - diff --git a/public/docs/guides/index.html b/public/docs/guides/index.html deleted file mode 100644 index cce6d38..0000000 --- a/public/docs/guides/index.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - -Guides – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - -
Documentation
-
-
-
- - - - -
- -
- -Guides - - - - What is gRPC? - - - - - gRPC Concepts - - - - - Authentication - - - - - Error handling and debugging - - - - - Benchmarking - - - - - gRPC Wire Format - - - -Related Guides - Protocol Buffers -
- -
-

- Guides -

- - - -

This document introduces you to gRPC and protocol buffers. gRPC can use -protocol buffers as both its Interface Definition Language (IDL) and as its underlying message -interchange format. If you’re new to gRPC and/or protocol buffers, read this! -If you just want to dive in and see gRPC in action first, -see our Quick Starts.

- -
- -

Overview

- -

In gRPC a client application can directly call methods on a server application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub (referred to as just a client in some languages) that provides the same methods as the server.

- -

Concept Diagram

- -

gRPC clients and servers can run and talk to each other in a variety of environments - from servers inside Google to your own desktop - and can be written in any of gRPC’s supported languages. So, for example, you can easily create a gRPC server in Java with clients in Go, Python, or Ruby. In addition, the latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications.

- -

Working with Protocol Buffers

- -

By default gRPC uses protocol buffers, Google’s -mature open source mechanism for serializing structured data (although it -can be used with other data formats such as JSON). Here’s a quick intro to how -it works. If you’re already familiar with protocol buffers, feel free to skip -ahead to the next section.

- -

The first step when working with protocol buffers is to define the structure -for the data you want to serialize in a proto file: this is an ordinary text -file with a .proto extension. Protocol buffer data is structured as -messages, where each message is a small logical record of information -containing a series of name-value pairs called fields. Here’s a simple -example:

-
message Person {
-  string name = 1;
-  int32 id = 2;
-  bool has_ponycopter = 3;
-}
-

Then, once you’ve specified your data structures, you use the protocol buffer -compiler protoc to generate data access classes in your preferred language(s) -from your proto definition. These provide simple accessors for each field -(like name() and set_name()) as well as methods to serialize/parse -the whole structure to/from raw bytes – so, for instance, if your chosen -language is C++, running the compiler on the above example will generate a -class called Person. You can then use this class in your application to -populate, serialize, and retrieve Person protocol buffer messages.

- -

As you’ll see in more detail in our examples, you define gRPC services -in ordinary proto files, with RPC method parameters and return types specified as -protocol buffer messages:

-
// The greeter service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

gRPC also uses protoc with a special gRPC plugin to -generate code from your proto file. However, with the gRPC plugin, you get -generated gRPC client and server code, as well as the regular protocol buffer -code for populating, serializing, and retrieving your message types. We’ll -look at this example in more detail below.

- -

You can find out lots more about protocol buffers in the Protocol Buffers -documentation, -and find out how to get and install protoc with gRPC plugins in your chosen -language’s Quickstart.

- -

Protocol buffer versions

- -

While protocol buffers have been available for open source users for some -time, our examples use a new flavor of protocol buffers called proto3, which -has a slightly simplified syntax, some useful new features, and supports -lots more languages. This is currently available in Java, C++, Python, -Objective-C, C#, a lite-runtime (Android Java), Ruby, and JavaScript from the -protocol buffers GitHub repo, -as well as a Go language generator from the golang/protobuf GitHub -repo, with more languages -in development. You can find out more in the proto3 language -guide and the -reference documentation -available for each language. The reference documentation also includes a -formal specification -for the .proto file format.

- -

In general, while you can use proto2 (the current default protocol buffers -version), we recommend that you use proto3 with gRPC as it lets you use the -full range of gRPC-supported languages, as well as avoiding compatibility -issues with proto2 clients talking to proto3 servers and vice versa.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/guides/index.xml b/public/docs/guides/index.xml deleted file mode 100644 index 8678aae..0000000 --- a/public/docs/guides/index.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - Guides on gRPC - https://cjyabraham.github.io/docs/guides/ - Recent content in Guides on gRPC - Hugo -- gohugo.io - en-us - - - - - - Authentication - https://cjyabraham.github.io/docs/guides/auth/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/guides/auth/ - This document provides an overview of gRPC authentication, including our built-in supported auth mechanisms, how to plug in your own authentication systems, and examples of how to use gRPC auth in our supported languages. - Overview gRPC is designed to work with a variety of authentication mechanisms, making it easy to safely use gRPC to talk to other systems. You can use our supported mechanisms - SSL/TLS with or without Google token-based authentication - or you can plug in your own authentication system by extending our provided code. - - - - Benchmarking - https://cjyabraham.github.io/docs/guides/benchmarking/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/guides/benchmarking/ - gRPC is designed to support high-performance open-source RPCs in many languages. This document describes the performance benchmarking tools, the scenarios considered by the tests, and the testing infrastructure. - -Overview gRPC is designed for both high-performance and high-productivity design of distributed applications. Continuous performance benchmarking is a critical part of the gRPC development workflow. Multi-language performance tests run hourly against the master branch, and these numbers are reported to a dashboard for visualization. - - - - Contribution Guidelines - https://cjyabraham.github.io/docs/guides/contributing/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/guides/contributing/ - Contribution Guidelines Coming soon! - - - - Error Handling - https://cjyabraham.github.io/docs/guides/error/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/guides/error/ - This page describes how gRPC deals with errors, including gRPC's built-in error codes. Example code in different languages can be found here. - Error model As you&rsquo;ll have seen in our concepts document and examples, when a gRPC call completes successfully the server returns an OK status to the client (depending on the language the OK status may or may not be directly used in your code). But what happens if the call isn&rsquo;t successful? - - - - gRPC Concepts - https://cjyabraham.github.io/docs/guides/concepts/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/guides/concepts/ - This document introduces some key gRPC concepts with an overview of gRPC's architecture and RPC life cycle. -It assumes that you&rsquo;ve read What is gRPC?. For language-specific details, see the Quick Start, tutorial, and reference documentation for your chosen language(s), where available (complete reference docs are coming soon). - Overview Service definition Like many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. - - - - \ No newline at end of file diff --git a/public/docs/index.html b/public/docs/index.html deleted file mode 100644 index 8db043e..0000000 --- a/public/docs/index.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - - - Documentation – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- -
- Welcome to the developer documentation for gRPC. - Here you can learn about key gRPC concepts, find quick starts, reference - material, and tutorials for all our supported languages, and more. If you’re new to gRPC we recommend that you read What is - gRPC? to find out more about our system and how it works. Or, if you want to see gRPC in action first, visit the QuickStart for your favourite language. -
- - -
-

gRPC by Language

- -
- - -
-

gRPC by Use Cases

-
-
- gRPC is used in last mile of computing in mobile and web client since it can generate libraries for iOS and Android and uses standards based HTTP/2 as transport allowing it to easily traverse proxies and firewalls. There is also work underway to develop a JS library for use in browsers. Beyond that, it is ideal as a microservices interconnect, not just because the core protocol is very efficient but also because the framework has pluggable authentication, load balancing etc. Google itself is also transitioning to use it to connect microservices. -
- - - - - -
-
- - -
-

gRPC in Other Projects

-
-
- gRPC now has a vibrant community of companies, projects, developers who are extending and building around it. Here are some popular projects. -
- -
-
- -
- - - - - - - - - - diff --git a/public/docs/index.xml b/public/docs/index.xml deleted file mode 100644 index b043627..0000000 --- a/public/docs/index.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Documentation on gRPC - https://cjyabraham.github.io/docs/ - Recent content in Documentation on gRPC - Hugo -- gohugo.io - en-us - - - - - - \ No newline at end of file diff --git a/public/docs/quickstart/android.html b/public/docs/quickstart/android.html deleted file mode 100644 index d6b2159..0000000 --- a/public/docs/quickstart/android.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/android/ \ No newline at end of file diff --git a/public/docs/quickstart/android/index.html b/public/docs/quickstart/android/index.html deleted file mode 100644 index 4dd45af..0000000 --- a/public/docs/quickstart/android/index.html +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - - - - - - - Android Java Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Android Java Quickstart

- - - -

This guide gets you started with gRPC in Android Java with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- - - -

Note: gRPC Java does not support running a server on an Android device. For this -quickstart, the Android client app will connect to a server running on your -local (non-Android) computer.

- -

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository at the latest release to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc-java
-$ # Navigate to the Java examples:
-$ cd grpc-java/examples
-

Run a gRPC application

- -
    -
  1. Compile the server
  2. -
-
   $ ./gradlew installDist
-
    -
  1. Run the server
  2. -
-
   $ ./build/install/examples/bin/hello-world-server
-
    -
  1. In another terminal, compile and run the client
  2. -
-
   $ cd android/helloworld
-   $ ../../gradlew installDebug
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: Android Java. For now all you need to know is that both the -server and the client “stub” have a SayHello RPC method that takes a -HelloRequest parameter from the client and returns a HelloResponse from the -server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -src/main/proto/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Update and run the application

- -

When we recompile the example, normal compilation will regenerate -GreeterGrpc.java, which contains our generated gRPC client and server classes. -This also regenerates classes for populating, serializing, and retrieving our -request and response types.

- -

However, we still need to implement and call the new method in the human-written -parts of our example application.

- -

Update the server

- -

Check out the Java quickstart here.

- -

Update the client

- -

In the same directory, open -app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java. Call the new -method like this:

-
    try {
-        HelloRequest message = HelloRequest.newBuilder().setName(mMessage).build();
-        HelloReply reply = stub.sayHello(message);
-        reply = stub.sayHelloAgain(message);
-    } catch (Exception e) {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        e.printStackTrace(pw);
-        pw.flush();
-        return "Failed... : " + System.lineSeparator() + sw;
-    }
-

Run!

- -

Just like we did before, from the examples directory:

- -
    -
  1. Compile the server
  2. -
-
   $ ./gradlew installDist
-
    -
  1. Run the server
  2. -
-
   $ ./build/install/examples/bin/hello-world-server
-
    -
  1. In another terminal, compile and install the client to your device
  2. -
-
   $ cd android/helloworld
-   $ ../../gradlew installDebug
-

Connecting to the Hello World server via USB

- -

To run the application on a physical device via USB debugging, you must -configure USB port forwarding to allow the device to communicate with the server -running on your computer. This is done via the adb command line tool as -follows:

-
adb reverse tcp:8080 tcp:50051
-

This sets up port forwarding from port 8080 on the device to port 50051 on -the connected computer, which is the port that the Hello World server is -listening on.

- -

Now you can run the Android Hello World app on your device, using localhost -and 8080 as the Host and Port.

- -

Connecting to the Hello World server from an Android Virtual Device

- -

To run the Hello World app on an Android Virtual Device, you don’t need to -enable port forwarding. Instead, the emulator can use the IP address -10.0.2.2 to refer to the host machine. Inside the Android Hello World app, -enter 10.0.2.2 and 50051 as the Host and Port.

- -

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/cpp.html b/public/docs/quickstart/cpp.html deleted file mode 100644 index c7ef91f..0000000 --- a/public/docs/quickstart/cpp.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/cpp/ \ No newline at end of file diff --git a/public/docs/quickstart/cpp/index.html b/public/docs/quickstart/cpp/index.html deleted file mode 100644 index 16bf9ab..0000000 --- a/public/docs/quickstart/cpp/index.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - - - - - - C++ Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

C++ Quickstart

- - - -

This guide gets you started with gRPC in C++ with a simple -working example.

- -
- -

Before you begin

- -

Install gRPC

- -

To install gRPC on your system, follow the instructions to install gRPC C++ via make.

- -

To run the example code, please ensure pkg-config is installed on your -machine before you build and install gRPC in the previous step, since the -example Makefiles try to look up the installed gRPC path using pkg-config. -On Debian-based systems like Ubuntu, this can usually be done via -sudo apt-get install pkg-config.

- -

Install Protocol Buffers v3

- -

While not mandatory to use gRPC, gRPC applications usually leverage Protocol -Buffers v3 for service definitions and data serialization, and our example code -uses Protocol Buffers as well as gRPC. If you don’t already have it installed on -your system, you can install the version cloned alongside gRPC. First ensure -that you are running these commands in the gRPC tree you just built in the from -the previous step.

-
$ cd third_party/protobuf
-$ make && sudo make install
-

Build the example

- -

Always assuming you have gRPC properly installed, go into the example’s -directory:

-
$ cd examples/cpp/helloworld/
-

Let’s build the example client and server:

-
$ make
-

Most failures at this point are a result of a faulty installation (or having -installed gRPC to a non-standard location. Check out the installation -instructions for details).

- -

Try it!

- -

From the examples/cpp/helloworld directory, run the server, which will listen -on port 50051:

-
$ ./greeter_server
-

From a different terminal, run the client:

-
$ ./greeter_client
-

If things go smoothly, you will see the Greeter received: Hello world in the -client side output.

- -

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in What is gRPC? and gRPC Basics: -C++. For now all you need to know is that both the server and the client -“stub” have a SayHello RPC method that takes a HelloRequest parameter from -the client and returns a HelloResponse from the server, and that this method -is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto (from the root of the cloned repository) and -update it with a new SayHelloAgain method, with the same request and response -types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition. From the examples/cpp/helloworld directory:

-
$ make
-

This regenerates helloworld.pb.{h,cc} and helloworld.grpc.pb.{h,cc}, which -contains our generated client and server classes, as well as classes for -populating, serializing, and retrieving our request and response types.

- -

Update and run the application

- -

We now have new generated server and client code, but we still need to implement -and call the new method in the human-written parts of our example application.

- -

Update the server

- -

In the same directory, open greeter_server.cc. Implement the new method like -this:

-
class GreeterServiceImpl final : public Greeter::Service {
-  Status SayHello(ServerContext* context, const HelloRequest* request,
-                  HelloReply* reply) override {
-     // ... (pre-existing code)
-  }
-
-  Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
-                       HelloReply* reply) override {
-    std::string prefix("Hello again ");
-    reply->set_message(prefix + request->name());
-    return Status::OK;
-  }
-};
-
-

Update the client

- -

A new SayHelloAgain method is now available in the stub. We’ll follow the same -pattern as for the already present SayHello and add a new SayHelloAgain -method to GreeterClient:

-
class GreeterClient {
- public:
-  // ...
-  std::string SayHello(const std::string& user) {
-     // ...
-  }
-
-  std::string SayHelloAgain(const std::string& user) {
-    // Follows the same pattern as SayHello.
-    HelloRequest request;
-    request.set_name(user);
-    HelloReply reply;
-    ClientContext context;
-
-    // Here we can use the stub's newly available method we just added.
-    Status status = stub_->SayHelloAgain(&context, request, &reply);
-    if (status.ok()) {
-      return reply.message();
-    } else {
-      std::cout << status.error_code() << ": " << status.error_message()
-                << std::endl;
-      return "RPC failed";
-    }
-  }
-
-

Finally, we exercise this new method in main:

-
int main(int argc, char** argv) {
-  // ...
-  std::string reply = greeter.SayHello(user);
-  std::cout << "Greeter received: " << reply << std::endl;
-
-  reply = greeter.SayHelloAgain(user);
-  std::cout << "Greeter received: " << reply << std::endl;
-
-  return 0;
-}
-
-

Run!

- -

Just like we did before, from the examples/cpp/helloworld directory:

- -
    -
  1. Build the client and server after having made changes:

    -
    $ make
  2. - -
  3. Run the server

  4. -
-
   $ ./greeter_server
-
    -
  1. On a different terminal, run the client
  2. -
-
   $ ./greeter_client
-

You should see the updated output:

-
   $ ./greeter_client
-   Greeter received: Hello world
-   Greeter received: Hello again world
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/csharp.html b/public/docs/quickstart/csharp.html deleted file mode 100644 index d2c0445..0000000 --- a/public/docs/quickstart/csharp.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/csharp/ \ No newline at end of file diff --git a/public/docs/quickstart/csharp/index.html b/public/docs/quickstart/csharp/index.html deleted file mode 100644 index b61e7f0..0000000 --- a/public/docs/quickstart/csharp/index.html +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - - - - - - - C# Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

C# Quick Start

- - - -

This guide gets you started with gRPC in C# with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- -

Whether you’re using Windows, OS X, or Linux, you can follow this -example by using either an IDE and its build tools, -or by using the the .NET Core SDK command line tools.

- -

First, make sure you have installed the -gRPC C# prerequisites. -You will also need Git to download the sample code.

- -

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc 
-$ cd grpc
-

This document will walk you through the “Hello World” example. -The projects and source files can be found in the examples/csharp/Helloworld directory.

- -

The example in this walkthrough already adds the necessary -dependencies for you (Grpc, Grpc.Tools and Google.Protobuf NuGet packages).

- -

Build the example

- -

Using Visual Studio (or Visual Studio for Mac)

- - - -

Using .NET Core SDK from the command line

- -

From the examples/csharp/Helloworld directory:

-
> dotnet build Greeter.sln
-

NOTE: If you want to use gRPC C# from a project that uses the “classic” .csproj files (supported by Visual Studio 2013, 2015 and older versions of Mono), please refer to the -Greeter using “classic” .csproj example.

- -

Run a gRPC application

- -

From the examples/csharp/Helloworld directory:

- - -
> cd GreeterServer
-> dotnet run -f netcoreapp2.1
- -
> cd GreeterClient
-> dotnet run -f netcoreapp2.1
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: C#. For now all you need to know is that both the -server and the client “stub” have a SayHello RPC method that takes a -HelloRequest parameter from the client and returns a HelloResponse from the -server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new service definition.

- -

The Grpc.Tools NuGet package contains the protoc and protobuf C# plugin binaries needed -to generate the code. Starting from version 1.17 the package also integrates with -MSBuild to provide automatic C# code generation -from .proto files.

- -

This example project already depends on the Grpc.Tools.1.20.0 NuGet package so just re-building the solution -is enough to regenerate the code from our modified .proto file.

- -

You can rebuild just like we first built the original -example by running dotnet build Greeter.sln or by clicking “Build” in Visual Studio.

- -

The build regenerates the following files -under the Greeter/obj/Debug/TARGET_FRAMEWORK directory:

- - - -

Update and run the application

- -

We now have new generated server and client code, but we still need to implement -and call the new method in the human-written parts of our example application.

- -

Update the server

- -

With the Greeter.sln open in your IDE, open GreeterServer/Program.cs. -Implement the new method by editing the GreeterImpl class like this:

-
class GreeterImpl : Greeter.GreeterBase
-{
-    // Server side handler of the SayHello RPC
-    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
-    {
-        return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
-    }
-
-    // Server side handler for the SayHelloAgain RPC
-    public override Task<HelloReply> SayHelloAgain(HelloRequest request, ServerCallContext context)
-    {
-        return Task.FromResult(new HelloReply { Message = "Hello again " + request.Name });
-    }
-}
-
-

Update the client

- -

With the same Greeter.sln open in your IDE, open GreeterClient/Program.cs. -Call the new method like this:

-
public static void Main(string[] args)
-{
-    Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
-
-    var client = new Greeter.GreeterClient(channel);
-    String user = "you";
-
-    var reply = client.SayHello(new HelloRequest { Name = user });
-    Console.WriteLine("Greeting: " + reply.Message);
-    
-    var secondReply = client.SayHelloAgain(new HelloRequest { Name = user });
-    Console.WriteLine("Greeting: " + secondReply.Message);
-
-    channel.ShutdownAsync().Wait();
-    Console.WriteLine("Press any key to exit...");
-    Console.ReadKey();
-}
-
-

Rebuild the modified example

- -

Rebuild the newly modified example just like we first built the original -example by running dotnet build Greeter.sln or by clicking “Build” in Visual Studio.

- -

Run!

- -

Just like we did before, from the examples/csharp/Helloworld directory:

- - -
> cd GreeterServer
-> dotnet run -f netcoreapp2.1
- -
> cd GreeterClient
-> dotnet run -f netcoreapp2.1
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/dart.html b/public/docs/quickstart/dart.html deleted file mode 100644 index 40b9c5c..0000000 --- a/public/docs/quickstart/dart.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/dart/ \ No newline at end of file diff --git a/public/docs/quickstart/dart/index.html b/public/docs/quickstart/dart/index.html deleted file mode 100644 index cad31e9..0000000 --- a/public/docs/quickstart/dart/index.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - - - - - - - - Dart Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Dart Quickstart

- - - -

This guide gets you started with gRPC in Dart with a simple -working example.

- -
- -

Prerequisites

- -

Dart SDK

- -

gRPC requires Dart SDK version 2.0 or higher. Dart gRPC supports Flutter and Server platforms.

- -

For installation instructions, follow this guide: Install Dart

- -

Install Protocol Buffers v3

- -

While not mandatory to use gRPC, gRPC applications usually leverage Protocol -Buffers v3 for service definitions and data serialization, and our example code -uses Protocol Buffers as well as gRPC.

- -

The simplest way to install the protoc compiler is to download pre-compiled -binaries for your operating system (protoc-<version>-<os>.zip) from here: -https://github.com/google/protobuf/releases

- - - -

Next, install the protoc plugin for Dart

-
$ pub global activate protoc_plugin
-

The compiler plugin, protoc-gen-dart, is installed in $HOME/.pub-cache/bin. -It must be in your $PATH for the protocol compiler, protoc, to find it.

-
$ export PATH=$PATH:$HOME/.pub-cache/bin
-

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository at the latest release to get the example code:
-$ git clone https://github.com/grpc/grpc-dart
-$ # Navigate to the "Hello World" Dart example:
-$ cd grpc-dart/example/helloworld
-

Run a gRPC application

- -

From the example/helloworld directory:

- -
    -
  1. Download package dependencies
  2. -
-
   $ pub get
-
    -
  1. Run the server
  2. -
-
   $ dart bin/server.dart
-
    -
  1. In another terminal, run the client
  2. -
-
   $ dart bin/client.dart
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: Dart. For now all you need to know is that both the -server and the client “stub” have a SayHello RPC method that takes a -HelloRequest parameter from the client and returns a HelloReply from the -server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition.

- -

From the example/helloworld directory, run:

-
$ protoc --dart_out=grpc:lib/src/generated -Iprotos protos/helloworld.proto
-

This regenerates the files in lib/src/generated which contain our generated -request and response classes, and client and server classes.

- -

Update and run the application

- -

We now have new generated server and client code, but we still need to implement -and call the new method in the human-written parts of our example application.

- -

Update the server

- -

In the same directory, open bin/server.dart. Implement the new method like -this:

-
class GreeterService extends GreeterServiceBase {
-  @override
-  Future<HelloReply> sayHello(ServiceCall call, HelloRequest request) async {
-    return new HelloReply()..message = 'Hello, ${request.name}!';
-  }
-
-  @override
-  Future<HelloReply> sayHelloAgain(
-      ServiceCall call, HelloRequest request) async {
-    return new HelloReply()..message = 'Hello again, ${request.name}!';
-  }
-}
-...
-

Update the client

- -

In the same directory, open bin/client.dart. Call the new method like this:

-
Future<Null> main(List<String> args) async {
-  final channel = new ClientChannel('localhost',
-      port: 50051,
-      options: const ChannelOptions(
-          credentials: const ChannelCredentials.insecure()));
-  final stub = new GreeterClient(channel);
-
-  final name = args.isNotEmpty ? args[0] : 'world';
-
-  try {
-    var response = await stub.sayHello(new HelloRequest()..name = name);
-    print('Greeter client received: ${response.message}');
-    response = await stub.sayHelloAgain(new HelloRequest()..name = name);
-    print('Greeter client received: ${response.message}');
-  } catch (e) {
-    print('Caught error: $e');
-  }
-  await channel.shutdown();
-}
-

Run!

- -

Just like we did before, from the example/helloworld directory:

- -
    -
  1. Run the server
  2. -
-
   $ dart bin/server.dart
-
    -
  1. In another terminal, run the client
  2. -
-
   $ dart bin/client.dart
-

What’s next

- - - -

Reporting issues

- -

Should you encounter an issue, please help us out by -filing issues -in our issue tracker.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/go.html b/public/docs/quickstart/go.html deleted file mode 100644 index 221efab..0000000 --- a/public/docs/quickstart/go.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/go/ \ No newline at end of file diff --git a/public/docs/quickstart/go/index.html b/public/docs/quickstart/go/index.html deleted file mode 100644 index ca5ad3d..0000000 --- a/public/docs/quickstart/go/index.html +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - Go Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Go Quick Start

- - - -

This guide gets you started with gRPC in Go with a simple -working example.

- -
- -

Prerequisites

- -

Go version

- -

gRPC requires Go 1.6 or higher.

-
$ go version
-

For installation instructions, follow this guide: Getting Started - The Go Programming Language

- -

Install gRPC

- -

Use the following command to install gRPC.

-
$ go get -u google.golang.org/grpc
-

Install Protocol Buffers v3

- -

Install the protoc compiler that is used to generate gRPC service code. The simplest way to do this is to download pre-compiled binaries for your platform(protoc-<version>-<platform>.zip) from here: https://github.com/google/protobuf/releases

- - - -

Next, install the protoc plugin for Go

-
$ go get -u github.com/golang/protobuf/protoc-gen-go
-

The compiler plugin, protoc-gen-go, will be installed in $GOBIN, defaulting to $GOPATH/bin. It must be in your $PATH for the protocol compiler, protoc, to find it.

-
$ export PATH=$PATH:$GOPATH/bin
-

Download the example

- -

The grpc code that was fetched with go get google.golang.org/grpc also contains the examples. They can be found under the examples dir: $GOPATH/src/google.golang.org/grpc/examples.

- -

Build the example

- -

Change to the example directory

-
$ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
-

gRPC services are defined in a .proto file, which is used to generate a corresponding .pb.go file. The .pb.go file is generated by compiling the .proto file using the protocol compiler: protoc.

- -

For the purpose of this example, the helloworld.pb.go file has already been generated (by compiling helloworld.proto), and can be found in this directory: $GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld

- -

This helloworld.pb.go file contains:

- - - -

Try it!

- -

To compile and run the server and client code, the go run command can be used. -In the examples directory:

-
$ go run greeter_server/main.go
-

From a different terminal:

-
$ go run greeter_client/main.go
-

If things go smoothly, you will see the Greeting: Hello world in the client side output.

- -

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in What is gRPC? and gRPC Basics: -Go. For now all you need to know is that both the server and the client -“stub” have a SayHello RPC method that takes a HelloRequest parameter from -the client and returns a HelloReply from the server, and that this method -is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Make sure you are in the same examples dir as above ($GOPATH/src/google.golang.org/grpc/examples/helloworld)

- -

Edit helloworld/helloworld.proto and update it with a new SayHelloAgain method, with the same request and response -types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition. From the same examples dir as above ($GOPATH/src/google.golang.org/grpc/examples/helloworld)

-
$ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
-

This regenerates the helloworld.pb.go with our new changes.

- -

Update and run the application

- -

We now have new generated server and client code, but we still need to implement -and call the new method in the human-written parts of our example application.

- -

Update the server

- -

Edit greeter_server/main.go and add the following function to it:

-
func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
-        return &pb.HelloReply{Message: "Hello again " + in.Name}, nil
-}
-

Update the client

- -

Edit greeter_client/main.go to add the following code to the main function.

-
r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name})
-if err != nil {
-        log.Fatalf("could not greet: %v", err)
-}
-log.Printf("Greeting: %s", r.Message)
-

Run!

- -

Run the server

-
$ go run greeter_server/main.go
-

On a different terminal, run the client

-
$ go run greeter_client/main.go
-

You should see the updated output:

-
$ go run greeter_client/main.go
-Greeting: Hello world
-Greeting: Hello again world
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/index.html b/public/docs/quickstart/index.html deleted file mode 100644 index a4a32c4..0000000 --- a/public/docs/quickstart/index.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Quick Start

- -

-Get started with gRPC -

- -
- -

These pages show you how to get up and running as quickly as possible in gRPC, -including installing all the tools you’ll need.

- -

There is a Quick Start for each gRPC supported language with accompanying sample -code for a simple Hello World example for you to explore and update.

- -

For an overview of some of the core concepts in gRPC, see gRPC Concepts. -For more tutorials and examples, see our Tutorials. -You can read more about gRPC in general in What is gRPC?.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/index.xml b/public/docs/quickstart/index.xml deleted file mode 100644 index 963862b..0000000 --- a/public/docs/quickstart/index.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - - Quick Start on gRPC - https://cjyabraham.github.io/docs/quickstart/ - Recent content in Quick Start on gRPC - Hugo -- gohugo.io - en-us - - - - - - Android Java Quickstart - https://cjyabraham.github.io/docs/quickstart/android/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/android/ - This guide gets you started with gRPC in Android Java with a simple working example. - Before you begin Prerequisites JDK: version 7 or higher Android SDK: API level 14 or higher An android device set up for USB debugging or an Android Virtual Device Note: gRPC Java does not support running a server on an Android device. For this quickstart, the Android client app will connect to a server running on your local (non-Android) computer. - - - - C# Quick Start - https://cjyabraham.github.io/docs/quickstart/csharp/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/csharp/ - This guide gets you started with gRPC in C# with a simple working example. - Before you begin Prerequisites Whether you&rsquo;re using Windows, OS X, or Linux, you can follow this example by using either an IDE and its build tools, or by using the the .NET Core SDK command line tools. -First, make sure you have installed the gRPC C# prerequisites. You will also need Git to download the sample code. - - - - C++ Quickstart - https://cjyabraham.github.io/docs/quickstart/cpp/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/cpp/ - This guide gets you started with gRPC in C++ with a simple working example. - Before you begin Install gRPC To install gRPC on your system, follow the instructions to install gRPC C++ via make. -To run the example code, please ensure pkg-config is installed on your machine before you build and install gRPC in the previous step, since the example Makefiles try to look up the installed gRPC path using pkg-config. - - - - Dart Quickstart - https://cjyabraham.github.io/docs/quickstart/dart/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/dart/ - This guide gets you started with gRPC in Dart with a simple working example. - Prerequisites Dart SDK gRPC requires Dart SDK version 2.0 or higher. Dart gRPC supports Flutter and Server platforms. -For installation instructions, follow this guide: Install Dart -Install Protocol Buffers v3 While not mandatory to use gRPC, gRPC applications usually leverage Protocol Buffers v3 for service definitions and data serialization, and our example code uses Protocol Buffers as well as gRPC. - - - - Go Quick Start - https://cjyabraham.github.io/docs/quickstart/go/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/go/ - This guide gets you started with gRPC in Go with a simple working example. - Prerequisites Go version gRPC requires Go 1.6 or higher. -$ go version For installation instructions, follow this guide: Getting Started - The Go Programming Language -Install gRPC Use the following command to install gRPC. -$ go get -u google.golang.org/grpc Install Protocol Buffers v3 Install the protoc compiler that is used to generate gRPC service code. - - - - Java Quickstart - https://cjyabraham.github.io/docs/quickstart/java/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/java/ - This guide gets you started with gRPC in Java with a simple working example. - Before you begin Prerequisites JDK: version 7 or higher Download the example You&rsquo;ll need a local copy of the example code to work through this quickstart. Download the example code from our GitHub repository (the following command clones the entire repository, but you just need the examples for this quickstart and other tutorials): - - - - Node Quick Start - https://cjyabraham.github.io/docs/quickstart/node/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/node/ - This guide gets you started with gRPC in Node with a simple working example. - Before you begin Prerequisites node: version 4.0.0 or higher Download the example You&rsquo;ll need a local copy of the example code to work through this quickstart. Download the example code from our GitHub repository (the following command clones the entire repository, but you just need the examples for this quickstart and other tutorials): - - - - Objective-C Quickstart - https://cjyabraham.github.io/docs/quickstart/objective-c/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/objective-c/ - This guide gets you started with gRPC on the iOS platform in Objective-C with a simple working example. - Before you begin System requirement The minimum deployment iOS version for gRPC is 7.0. -OS X El Capitan (version 10.11) or above is required to build and run this Quickstart. -Prerequisites CocoaPods: version 1.0 or higher - Check status and version of CocoaPods on your system with command pod --version. - - - - PHP Quickstart - https://cjyabraham.github.io/docs/quickstart/php/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/php/ - This guide gets you started with gRPC in PHP with a simple working example. - Prerequisites php 5.5 or above, 7.0 or above pecl composer phpunit (optional) Install PHP and PECL on Ubuntu/Debian: -For PHP5: -$ sudo apt-get install php5 php5-dev php-pear phpunit For PHP7: -$ sudo apt-get install php7.0 php7.0-dev php-pear phpunit or -$ sudo apt-get install php php-dev php-pear phpunit Install PHP and PECL on CentOS/RHEL 7: - - - - Python Quickstart - https://cjyabraham.github.io/docs/quickstart/python/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/python/ - This guide gets you started with gRPC in Python with a simple working example. - Before you begin Prerequisites gRPC Python is supported for use with Python 2.7 or Python 3.4 or higher. -Ensure you have pip version 9.0.1 or higher: -$ python -m pip install --upgrade pip If you cannot upgrade pip due to a system-owned installation, you can run the example in a virtualenv: -$ python -m pip install virtualenv $ virtualenv venv $ source venv/bin/activate $ python -m pip install --upgrade pip Install gRPC Install gRPC: - - - - Ruby Quick Start - https://cjyabraham.github.io/docs/quickstart/ruby/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/ruby/ - This guide gets you started with gRPC in Ruby with a simple working example. - Before you begin Prerequisites ruby: version 2 or higher Install gRPC $ gem install grpc Install gRPC tools Ruby&rsquo;s gRPC tools include the protocol buffer compiler protoc and the special plugin for generating server and client code from the .proto service definitions. For the first part of our quickstart example, we&rsquo;ve already generated the server and client stubs from helloworld. - - - - Web Quick Start - https://cjyabraham.github.io/docs/quickstart/web/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/quickstart/web/ - This guide gets you started with gRPC-Web with a simple working example from the browser. - Prerequisites docker and docker-compose This demo requires Docker Compose file version 3. Please refer to Docker website on how to install Docker. -Run an Echo example from the browser! $ git clone https://github.com/grpc/grpc-web $ cd grpc-web $ docker-compose pull $ docker-compose up -d node-server envoy commonjs-client Open a browser tab, and go to: - - - - \ No newline at end of file diff --git a/public/docs/quickstart/java.html b/public/docs/quickstart/java.html deleted file mode 100644 index d91603a..0000000 --- a/public/docs/quickstart/java.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/java/ \ No newline at end of file diff --git a/public/docs/quickstart/java/index.html b/public/docs/quickstart/java/index.html deleted file mode 100644 index fe511f5..0000000 --- a/public/docs/quickstart/java/index.html +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - - - - - - - Java Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Java Quickstart

- - - -

This guide gets you started with gRPC in Java with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- - - -

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository at the latest release to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc-java
-$ # Navigate to the Java examples:
-$ cd grpc-java/examples
-

Run a gRPC application

- -

From the examples directory:

- -
    -
  1. Compile the client and server
  2. -
-
   $ ./gradlew installDist
-
    -
  1. Run the server
  2. -
-
   $ ./build/install/examples/bin/hello-world-server
-
    -
  1. In another terminal, run the client
  2. -
-
   $ ./build/install/examples/bin/hello-world-client
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: Java. For now all you need to know is that both the -server and the client “stub” have a SayHello RPC method that takes a -HelloRequest parameter from the client and returns a HelloReply from the -server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -src/main/proto/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Update and run the application

- -

When we recompile the example, normal compilation will regenerate -GreeterGrpc.java, which contains our generated gRPC client and server classes. -This also regenerates classes for populating, serializing, and retrieving our -request and response types.

- -

However, we still need to implement and call the new method in the human-written -parts of our example application.

- -

Update the server

- -

In the same directory, open -src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java. Implement the -new method like this:

-
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
-
-  @Override
-  public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
-    HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
-    responseObserver.onNext(reply);
-    responseObserver.onCompleted();
-  }
-
-  @Override
-  public void sayHelloAgain(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
-    HelloReply reply = HelloReply.newBuilder().setMessage("Hello again " + req.getName()).build();
-    responseObserver.onNext(reply);
-    responseObserver.onCompleted();
-  }
-}
-...
-

Update the client

- -

In the same directory, open -src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java. Call the new -method like this:

-
public void greet(String name) {
-  logger.info("Will try to greet " + name + " ...");
-  HelloRequest request = HelloRequest.newBuilder().setName(name).build();
-  HelloReply response;
-  try {
-    response = blockingStub.sayHello(request);
-  } catch (StatusRuntimeException e) {
-    logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
-    return;
-  }
-  logger.info("Greeting: " + response.getMessage());
-  try {
-    response = blockingStub.sayHelloAgain(request);
-  } catch (StatusRuntimeException e) {
-    logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
-    return;
-  }
-  logger.info("Greeting: " + response.getMessage());
-}
-

Run!

- -

Just like we did before, from the examples directory:

- -
    -
  1. Compile the client and server
  2. -
-
   $ ./gradlew installDist
-
    -
  1. Run the server
  2. -
-
   $ ./build/install/examples/bin/hello-world-server
-
    -
  1. In another terminal, run the client
  2. -
-
   $ ./build/install/examples/bin/hello-world-client
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/node.html b/public/docs/quickstart/node.html deleted file mode 100644 index 01989e1..0000000 --- a/public/docs/quickstart/node.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/node/ \ No newline at end of file diff --git a/public/docs/quickstart/node/index.html b/public/docs/quickstart/node/index.html deleted file mode 100644 index 6fcd95c..0000000 --- a/public/docs/quickstart/node/index.html +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - Node Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Node Quick Start

- - - -

This guide gets you started with gRPC in Node with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- - - -

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository to get the example code
-$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ # Navigate to the dynamic codegen "hello, world" Node example:
-$ cd grpc/examples/node/dynamic_codegen
-$ # Install the example's dependencies
-$ npm install
-

Run a gRPC application

- -

From the examples/node/dynamic_codegen directory:

- -
    -
  1. Run the server

    -
    $ node greeter_server.js
  2. - -
  3. In another terminal, run the client

    -
    $ node greeter_client.js
  4. -
- -

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: Node. For now all you need -to know is that both the server and the client “stub” have a SayHello RPC -method that takes a HelloRequest parameter from the client and returns a -HelloReply from the server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Update and run the application

- -

We now have a new service definition, but we still need to implement and call -the new method in the human-written parts of our example application.

- -

Update the server

- -

In the same directory, open greeter_server.js. Implement the new method like -this:

-
function sayHello(call, callback) {
-  callback(null, {message: 'Hello ' + call.request.name});
-}
-
-function sayHelloAgain(call, callback) {
-  callback(null, {message: 'Hello again, ' + call.request.name});
-}
-
-function main() {
-  var server = new grpc.Server();
-  server.addProtoService(hello_proto.Greeter.service,
-                         {sayHello: sayHello, sayHelloAgain: sayHelloAgain});
-  server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
-  server.start();
-}
-...
-
-

Update the client

- -

In the same directory, open greeter_client.js. Call the new method like this:

-
function main() {
-  var client = new hello_proto.Greeter('localhost:50051',
-                                       grpc.credentials.createInsecure());
-  client.sayHello({name: 'you'}, function(err, response) {
-    console.log('Greeting:', response.message);
-  });
-  client.sayHelloAgain({name: 'you'}, function(err, response) {
-    console.log('Greeting:', response.message);
-  });
-}
-
-

Run!

- -

Just like we did before, from the examples/node/dynamic_codegen directory:

- -
    -
  1. Run the server

    -
    $ node greeter_server.js
  2. - -
  3. In another terminal, run the client

    -
    $ node greeter_client.js
  4. -
- -

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/objective-c.html b/public/docs/quickstart/objective-c.html deleted file mode 100644 index 90c1b7a..0000000 --- a/public/docs/quickstart/objective-c.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/objective-c/ \ No newline at end of file diff --git a/public/docs/quickstart/objective-c/index.html b/public/docs/quickstart/objective-c/index.html deleted file mode 100644 index fc2113c..0000000 --- a/public/docs/quickstart/objective-c/index.html +++ /dev/null @@ -1,445 +0,0 @@ - - - - - - - - - - - - Objective-C Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Objective-C Quickstart

- - - -

This guide gets you started with gRPC on the iOS platform in -Objective-C with a simple working example.

- -
- -

Before you begin

- -

System requirement

- -

The minimum deployment iOS version for gRPC is 7.0.

- -

OS X El Capitan (version 10.11) or above is required to build and run this -Quickstart.

- -

Prerequisites

- - - -

Download the example

- -

You’ll need a local copy of the sample app source code to work through this -Quickstart. Copy the source code from GitHub -repository:

-
$ git clone --recursive -b v1.20.0 https://github.com/grpc/grpc.git
-

Install gRPC plugins and libraries

-
$ cd grpc
-$ make
-$ [sudo] make install
-

Install protoc compiler

-
$ brew tap grpc/grpc
-$ brew install protobuf
-

Run the server

- -

For this sample app, we need a gRPC server running on the local machine. gRPC -Objective-C API supports creating gRPC clients but not gRPC servers. Therefore -instead we build and run the C++ server in the same repository:

-
$ cd examples/cpp/helloworld
-$ make
-$ ./greeter_server &
-

Run the client

- -

Generate client libraries and dependencies

- -

Have CocoaPods generate and install the client library from our .proto files, as -well as installing several dependencies:

-
$ cd ../../objective-c/helloworld
-$ pod install
-

(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods -doesn’t have it yet on your computer’s cache.)

- -

Run the client app

- -

Open the Xcode workspace created by CocoaPods:

-
$ open HelloWorld.xcworkspace
-

This will open the app project with Xcode. Run the app in an iOS simulator -by pressing the Run button on the top left corner of Xcode window. You can check -the calling code in main.m and see the results in Xcode’s console.

- -

The code sends a HLWHelloRequest containing the string “Objective-C” to a -local server. The server responds with a HLWHelloResponse, which contains a -string “Hello Objective-C” that is then output to the console.

- -

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using Protocol -Buffers; you can find out lots more about how to define a service in a .proto -file in Protocol Buffers -website. For now all you -need to know is that both the server and the client “stub” have a SayHello -RPC method that takes a HelloRequest parameter from the client and returns a -HelloResponse from the server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Update the client and server

- -

We now have a new gRPC service definition, but we still need to implement and -call the new method in the human-written parts of our example application.

- -

Update the server

- -

As you remember, gRPC doesn’t provide a server API for Objective-C. Instead, we -need to update the C++ sample server. Open -examples/cpp/helloworld/greeter_server.cc. Implement the new method like this:

-
class GreeterServiceImpl final : public Greeter::Service {
-  Status SayHello(ServerContext* context, const HelloRequest* request,
-                  HelloReply* reply) override {
-    std::string prefix("Hello ");
-    reply->set_message(prefix + request->name());
-    return Status::OK;
-  }
-  Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
-                  HelloReply* reply) override {
-    std::string prefix("Hello again ");
-    reply->set_message(prefix + request->name());
-    return Status::OK;
-  }
-};
-
-

Update the client

- -

Edit examples/objective-c/helloworld/main.m to call the new method like this:

-
int main(int argc, char * argv[]) {
-  @autoreleasepool {
-    [GRPCCall useInsecureConnectionsForHost:kHostAddress];
-    [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress];
-
-    HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];
-
-    HLWHelloRequest *request = [HLWHelloRequest message];
-    request.name = @"Objective-C";
-
-    [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
-      NSLog(@"%@", response.message);
-    }];
-    [client sayHelloAgainWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
-      NSLog(@"%@", response.message);
-    }];
-
-    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
-  }
-}
-

Build and run

- -

First terminate the server process already running in the background:

-
$ pkill greeter_server
-

Then in directory examples/cpp/helloworld, build and run the updated server -with the following commands:

-
$ make
-$ ./greeter_server &
-

Change directory to examples/objective-c/helloworld, then clean up and -reinstall Pods for the client app with the following commands:

-
$ rm -Rf Pods
-$ rm Podfile.lock
-$ rm -Rf HelloWorld.xcworkspace
-$ pod install
-

This regenerates files in Pods/HelloWorld based on the new proto file we wrote -above. Open the client Xcode project in Xcode:

-
$ open HelloWorld.xcworkspace
-

and run the client app. If you look at the console messages, you should see two RPC calls, -one to SayHello and one to SayHelloAgain.

- -

Troubleshooting

- -

When installing CocoaPods, error prompt activesupport requires Ruby version >= 2.2.2.

- -

Install an older version of activesupport, then install CocoaPods:

-
[sudo] gem install activesupport -v 4.2.6
-[sudo] gem install cocoapods
-

When installing dependencies with CocoaPods, error prompt Unable to find a specification for !ProtoCompiler-gRPCPlugin

- -

Update the local clone of spec repo by running pod repo update

- -

Compiler error when compiling objective_c_plugin.cc

- -

Removing protobuf package with Homebrew before building gRPC may solve -this problem. We are working on a more elegant fix.

- -

When building HellowWorld, error prompt ld: unknown option: --no-as-needed

- -

This problem is due to linker ld in Apple LLVM not supporting the -–no-as-needed option. We are working on a fix right now and will merge the fix -very soon.

- -

When building grpc, error prompt cannot find install-sh install.sh or shtool

- -

Remove the gRPC directory, clone a new one and try again. It is likely that some -auto generated files are corrupt; remove and rebuild may solve the problem.

- -

When building grpc, error prompt Can't exec "aclocal"

- -

The package automake is missing. Install automake should solve this problem.

- -

When building grpc, error prompt possibly undefined macro: AC_PROG_LIBTOOL

- -

The package libtool is missing. Install libtool should solve this problem.

- -

When building grpc, error prompt cannot find install-sh, install.sh, or shtool

- -

Some of the auto generated files are corrupt. Remove the entire gRPC directory, -clone from GitHub, and build again.

- -

Cannot find protoc when building HelloWorld

- -

Run brew install protobuf to get protoc compiler.

- -

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/php.html b/public/docs/quickstart/php.html deleted file mode 100644 index cbc7532..0000000 --- a/public/docs/quickstart/php.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/php/ \ No newline at end of file diff --git a/public/docs/quickstart/php/index.html b/public/docs/quickstart/php/index.html deleted file mode 100644 index f6773be..0000000 --- a/public/docs/quickstart/php/index.html +++ /dev/null @@ -1,549 +0,0 @@ - - - - - - - - - - - - PHP Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

PHP Quickstart

- - - -

This guide gets you started with gRPC in PHP with a simple -working example.

- -
- -

Prerequisites

- - - -

Install PHP and PECL on Ubuntu/Debian:

- -

For PHP5:

-
$ sudo apt-get install php5 php5-dev php-pear phpunit
-

For PHP7:

-
$ sudo apt-get install php7.0 php7.0-dev php-pear phpunit
-

or

-
$ sudo apt-get install php php-dev php-pear phpunit
-

Install PHP and PECL on CentOS/RHEL 7:

-
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
-$ sudo rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
-$ sudo yum install php56w php56w-devel php-pear phpunit gcc zlib-devel
-

Install PHP and PECL on Mac:

-
$ brew install homebrew/php/php56-grpc
-$ curl -O http://pear.php.net/go-pear.phar
-$ sudo php -d detect_unicode=0 go-pear.phar
-

Install Composer (Linux or Mac):

-
$ curl -sS https://getcomposer.org/installer | php
-$ sudo mv composer.phar /usr/local/bin/composer
-

Install PHPUnit (Linux or Mac):

-
$ wget https://phar.phpunit.de/phpunit-old.phar
-$ chmod +x phpunit-old.phar
-$ sudo mv phpunit-old.phar /usr/bin/phpunit
-

Install the gRPC PHP extension

- -

There are two ways to install gRPC PHP extension. -* pecl -* build from source

- -

Using PECL

-
sudo pecl install grpc
-

or specific version

-
sudo pecl install grpc-1.7.0
-

Note: for users on CentOS/RHEL 6, unfortunately this step won’t work. -Please follow the instructions below to compile the PECL extension from source.

- -
Install on Windows
- -

You can download the pre-compiled gRPC extension from the PECL -website

- -

Build from Source with gRPC C core library

- -

Clone this repository

-
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
-
Build and install the gRPC C core library
-
$ cd grpc
-$ git submodule update --init
-$ make
-$ sudo make install
-
Build and install gRPC PHP extension
- -

Compile the gRPC PHP extension

-
$ cd grpc/src/php/ext/grpc
-$ phpize
-$ ./configure
-$ make
-$ sudo make install
-

This will compile and install the gRPC PHP extension into the -standard PHP extension directory. You should be able to run -the unit tests, with the PHP extension installed.

- -

Update php.ini

- -

After installing the gRPC extension, make sure you add this line -to your php.ini file, (e.g. /etc/php5/cli/php.ini, -/etc/php5/apache2/php.ini, or /usr/local/etc/php/5.6/php.ini), -depending on where your PHP installation is.

-
extension=grpc.so
-

Add the gRPC PHP library as a Composer dependency

- -

You need to add this to your project’s composer.json file.

-
  "require": {
-    "grpc/grpc": "v1.7.0"
-  }
-

To run tests with generated stub code from .proto files, you will also -need the composer and protoc binaries. You can find out how to get these below.

- -

Install other prerequisites for both Mac OS X and Linux

- - - -

Install Protobuf compiler

- -

If you don’t have it already, you need to install the protobuf compiler -protoc, version 3.4.0+ (the newer the better) for the current gRPC version. -If you installed already, make sure the protobuf version is compatible with the -grpc version you installed. If you build grpc.so from source, you can check -the version of grpc inside package.xml file.

- -

The compatibility between the grpc and protobuf version is listed as table below:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
grpcprotobuf
v1.0.03.0.0(GA)
v1.0.13.0.2
v1.1.03.1.0
v1.2.03.2.0
v1.2.03.2.0
v1.3.43.3.0
v1.3.53.2.0
v1.4.03.3.0
v1.6.03.4.0
- -

If protoc hasn’t been installed, you can download the protoc binaries from -the protocol buffers GitHub repository. -Then unzip this file and Update the environment variable PATH to include the path to -the protoc binary file./protobuf/releases). -Then unzip this file and Update the environment variable PATH to include the path to -the protoc binary file.

- -

If you really must compile protoc from source, you can run the following -commands, but this is risky because there is no easy way to uninstall / -upgrade to a newer release.

-
$ cd grpc/third_party/protobuf
-$ ./autogen.sh && ./configure && make
-$ sudo make install
-

Protobuf Runtime library

- -

There are two protobuf runtime libraries to choose from. They are identical -in terms of APIs offered. The C implementation provides better performance, -while the native implementation is easier to install. Make sure the installed -protobuf version works with grpc version.

- -
1. C implementation (for better performance)
-
$ sudo pecl install protobuf
-

or specific version

-
$ sudo pecl install protobuf-3.4.0
-

After protobuf extension is installed, Update php.ini by adding this line -to your php.ini file, (e.g. /etc/php5/cli/php.ini, -/etc/php5/apache2/php.ini, or /usr/local/etc/php/5.6/php.ini), -depending on where your PHP installation is.

-
extension=protobuf.so
-
2. PHP implementation (for easier installation)
- -

Add this to your composer.json file:

-
  "require": {
-    "google/protobuf": "^v3.3.0"
-  }
-

PHP Protoc Plugin

- -

You need the gRPC PHP protoc plugin to generate the client stub classes. -It can generate server and client code from .proto service definitions.

- -

It should already been compiled when you run make from the root directory -of this repo. The plugin can be found in the bins/opt directory. We are -planning to provide a better way to download and install the plugin -in the future.

- -

You can also just build the gRPC PHP protoc plugin by running:

-
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
-$ cd grpc
-$ git submodule update --init
-$ make grpc_php_plugin
-

Plugin may use the new feature of the new protobuf version, thus please also -make sure that the protobuf version installed is compatible with the grpc version -you build this plugin.

- -

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

- -

Note that currently you can only create clients in PHP for gRPC services - -you can find out how to create gRPC servers in our other tutorials, -e.g. Node.js.

-
$ # Clone the repository to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ # Build grpc_php_plugin to generate proto files if not build before
-$ cd grpc && git submodule update --init && make grpc_php_plugin
-$ # Navigate to the "hello, world" PHP example:
-$ cd examples/php
-$ ./greeter_proto_gen.sh
-$ composer install
-

Run a gRPC application

- -

From the examples/node directory:

- -
    -
  1. Run the server
  2. -
-
   $ npm install
-   $ cd dynamic_codegen
-   $ node greeter_server.js
-

In another terminal, from the examples/php directory:

- -
    -
  1. Run the client
  2. -
-
   $ ./run_greeter_client.sh
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: PHP. For now all you need to know is that both the -server and the client “stub” have a SayHello RPC method that takes a -HelloRequest parameter from the client and returns a HelloResponse from -the server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition. From the grpc root directory:

-
$ protoc --proto_path=examples/protos \
-  --php_out=examples/php \
-  --grpc_out=examples/php \
-  --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \
-  ./examples/protos/helloworld.proto
-

or running the helper script under the grpc/example/php directory if you build -grpc-php-plugin by source:

-
$ ./greeter_proto_gen.sh
-

This regenerates the protobuf files, which contain our generated client classes, -as well as classes for populating, serializing, and retrieving our request and -response types.

- -

Update and run the application

- -

We now have new generated client code, but we still need to implement and call -the new method in the human-written parts of our example application.

- -

Update the server

- -

In the same directory, open greeter_server.js. Implement the new method like -this:

-
function sayHello(call, callback) {
-  callback(null, {message: 'Hello ' + call.request.name});
-}
-
-function sayHelloAgain(call, callback) {
-  callback(null, {message: 'Hello again, ' + call.request.name});
-}
-
-function main() {
-  var server = new grpc.Server();
-  server.addProtoService(hello_proto.Greeter.service,
-                         {sayHello: sayHello, sayHelloAgain: sayHelloAgain});
-  server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
-  server.start();
-}
-...
-
-

Update the client

- -

In the same directory, open greeter_client.php. Call the new method like this:

-
    $request = new Helloworld\HelloRequest();
-    $request->setName($name);
-    list($reply, $status) = $client->SayHello($request)->wait();
-    $message = $reply->getMessage();
-    list($reply, $status) = $client->SayHelloAgain($request)->wait();
-    $message = $reply->getMessage();
-

Run!

- -

Just like we did before, from the examples/node/dynamic_codegen directory:

- -
    -
  1. Run the server
  2. -
-
   $ node greeter_server.js
-

In another terminal, from the examples/php directory:

- -
    -
  1. Run the client
  2. -
-
   $ ./run_greeter_client.sh
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/python.html b/public/docs/quickstart/python.html deleted file mode 100644 index 16eb44a..0000000 --- a/public/docs/quickstart/python.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/python/ \ No newline at end of file diff --git a/public/docs/quickstart/python/index.html b/public/docs/quickstart/python/index.html deleted file mode 100644 index fa0494f..0000000 --- a/public/docs/quickstart/python/index.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - Python Quickstart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Python Quickstart

- - - -

This guide gets you started with gRPC in Python with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- -

gRPC Python is supported for use with Python 2.7 or Python 3.4 or higher.

- -

Ensure you have pip version 9.0.1 or higher:

-
$ python -m pip install --upgrade pip
-

If you cannot upgrade pip due to a system-owned installation, you can -run the example in a virtualenv:

-
$ python -m pip install virtualenv
-$ virtualenv venv
-$ source venv/bin/activate
-$ python -m pip install --upgrade pip
-

Install gRPC

- -

Install gRPC:

-
$ python -m pip install grpcio
-

Or, to install it system wide:

-
$ sudo python -m pip install grpcio
-

On El Capitan OSX, you may get the following error:

-
$ OSError: [Errno 1] Operation not permitted: '/tmp/pip-qwTLbI-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'
-

You can work around this using:

-
$ python -m pip install grpcio --ignore-installed
-

Install gRPC tools

- -

Python’s gRPC tools include the protocol buffer compiler protoc and the -special plugin for generating server and client code from .proto service -definitions. For the first part of our quickstart example, we’ve already -generated the server and client stubs from -helloworld.proto, -but you’ll need the tools for the rest of our quickstart, as well as later -tutorials and your own projects.

- -

To install gRPC tools, run:

-
$ python -m pip install grpcio-tools
-

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ # Navigate to the "hello, world" Python example:
-$ cd grpc/examples/python/helloworld
-

Run a gRPC application

- -

From the examples/python/helloworld directory:

- -
    -
  1. Run the server
  2. -
-
   $ python greeter_server.py
-
    -
  1. In another terminal, run the client
  2. -
-
   $ python greeter_client.py
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in What is gRPC? and gRPC Basics: Python. For now all you need -to know is that both the server and the client “stub” have a SayHello RPC -method that takes a HelloRequest parameter from the client and returns a -HelloReply from the server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition.

- -

From the examples/python/helloworld directory, run:

-
$ python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto
-

This regenerates helloworld_pb2.py which contains our generated request and -response classes and helloworld_pb2_grpc.py which contains our generated -client and server classes.

- -

Update and run the application

- -

We now have new generated server and client code, but we still need to implement -and call the new method in the human-written parts of our example application.

- -

Update the server

- -

In the same directory, open greeter_server.py. Implement the new method like -this:

-
class Greeter(helloworld_pb2_grpc.GreeterServicer):
-
-  def SayHello(self, request, context):
-    return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
-
-  def SayHelloAgain(self, request, context):
-    return helloworld_pb2.HelloReply(message='Hello again, %s!' % request.name)
-...
-

Update the client

- -

In the same directory, open greeter_client.py. Call the new method like this:

-
def run():
-  channel = grpc.insecure_channel('localhost:50051')
-  stub = helloworld_pb2_grpc.GreeterStub(channel)
-  response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
-  print("Greeter client received: " + response.message)
-  response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='you'))
-  print("Greeter client received: " + response.message)
-

Run!

- -

Just like we did before, from the examples/python/helloworld directory:

- -
    -
  1. Run the server
  2. -
-
   $ python greeter_server.py
-
    -
  1. In another terminal, run the client
  2. -
-
   $ python greeter_client.py
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/ruby.html b/public/docs/quickstart/ruby.html deleted file mode 100644 index 3e8e5b3..0000000 --- a/public/docs/quickstart/ruby.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/ruby/ \ No newline at end of file diff --git a/public/docs/quickstart/ruby/index.html b/public/docs/quickstart/ruby/index.html deleted file mode 100644 index 07d0ab6..0000000 --- a/public/docs/quickstart/ruby/index.html +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - - - - - Ruby Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Ruby Quick Start

- - - -

This guide gets you started with gRPC in Ruby with a simple -working example.

- -
- -

Before you begin

- -

Prerequisites

- - - -

Install gRPC

- -
$ gem install grpc
-
- -

Install gRPC tools

- -

Ruby’s gRPC tools include the protocol buffer compiler protoc and the special -plugin for generating server and client code from the .proto service -definitions. For the first part of our quickstart example, we’ve already -generated the server and client stubs from -helloworld.proto, -but you’ll need the tools for the rest of our quickstart, as well as later -tutorials and your own projects.

- -

To install gRPC tools, run:

-
gem install grpc-tools
-

Download the example

- -

You’ll need a local copy of the example code to work through this quickstart. -Download the example code from our GitHub repository (the following command -clones the entire repository, but you just need the examples for this quickstart -and other tutorials):

-
$ # Clone the repository to get the example code:
-$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ # Navigate to the "hello, world" Ruby example:
-$ cd grpc/examples/ruby
-

Run a gRPC application

- -

From the examples/ruby directory:

- -
    -
  1. Run the server
  2. -
-
   $ ruby greeter_server.rb
-
    -
  1. In another terminal, run the client
  2. -
-
   $ ruby greeter_client.rb
-

Congratulations! You’ve just run a client-server application with gRPC.

- -

Update a gRPC service

- -

Now let’s look at how to update the application with an extra method on the -server for the client to call. Our gRPC service is defined using protocol -buffers; you can find out lots more about how to define a service in a .proto -file in gRPC Basics: Ruby. For now all you need -to know is that both the server and the client “stub” have a SayHello RPC -method that takes a HelloRequest parameter from the client and returns a -HelloResponse from the server, and that this method is defined like this:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

Let’s update this so that the Greeter service has two methods. Edit -examples/protos/helloworld.proto and update it with a new SayHelloAgain -method, with the same request and response types:

-
// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-  // Sends another greeting
-  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
-

(Don’t forget to save the file!)

- -

Generate gRPC code

- -

Next we need to update the gRPC code used by our application to use the new -service definition. From the examples/ruby/ directory:

-
$ grpc_tools_ruby_protoc -I ../protos --ruby_out=lib --grpc_out=lib ../protos/helloworld.proto
-

This regenerates lib/helloworld_services_pb.rb, which contains our generated -client and server classes.

- -

Update the server

- -

In the same directory, open greeter_server.rb. Implement the new method like this

-
class GreeterServer < Helloworld::Greeter::Service
-
-  def say_hello(hello_req, _unused_call)
-    Helloworld::HelloReply.new(message: "Hello #{hello_req.name}")
-  end
-
-  def say_hello_again(hello_req, _unused_call)
-    Helloworld::HelloReply.new(message: "Hello again, #{hello_req.name}")
-  end
-end
-...
-

Update the client

- -

In the same directory, open greeter_client.rb. Call the new method like this:

-
def main
-  stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
-  user = ARGV.size > 0 ?  ARGV[0] : 'world'
-  message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message
-  p "Greeting: #{message}"
-  message = stub.say_hello_again(Helloworld::HelloRequest.new(name: user)).message
-  p "Greeting: #{message}"
-end
-

Run!

- -

Just like we did before, from the examples/ruby directory:

- -
    -
  1. Run the server
  2. -
-
   $ ruby greeter_server.rb
-
    -
  1. In another terminal, run the client
  2. -
-
   $ ruby greeter_client.rb
-

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/quickstart/web.html b/public/docs/quickstart/web.html deleted file mode 100644 index cbfe533..0000000 --- a/public/docs/quickstart/web.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/quickstart/web/ \ No newline at end of file diff --git a/public/docs/quickstart/web/index.html b/public/docs/quickstart/web/index.html deleted file mode 100644 index fadf0ce..0000000 --- a/public/docs/quickstart/web/index.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - Web Quick Start – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Quick Start -C++ -C# -Dart -Go -Java -Android Java -Node.js -Objective-C -PHP -Python -Ruby -Web -
- -
-

Web Quick Start

- - - -

This guide gets you started with gRPC-Web with a simple -working example from the browser.

- -
- -

Prerequisites

- - - -

This demo requires Docker Compose file -version 3. Please refer to -Docker website on how to install Docker.

- -

Run an Echo example from the browser!

-
$ git clone https://github.com/grpc/grpc-web
-$ cd grpc-web
-$ docker-compose pull
-$ docker-compose up -d node-server envoy commonjs-client
-

Open a browser tab, and go to:

-
http://localhost:8081/echotest.html
-

To shutdown, run docker-compose down.

- -

What is Happening?

- -

In this demo, there are three key components:

- -
    -
  1. node-server: This is a standard gRPC Server, implemented in Node. -This server listens at port :9090 and implements the service’s business -logic.

  2. - -
  3. envoy: This is the Envoy proxy. It listens at :8080 and forwards the -browser’s gRPC-Web requests to port :9090. This is done via a config file -envoy.yaml.

  4. - -
  5. commonjs-client: This component generates the client stub class using -the protoc-gen-grpc-web protoc plugin, compiles all the JS dependencies -using webpack, and hosts the static content echotest.html and -dist/main.js using a simple web server at port :8081. Once the user -interacts with the webpage, it sends a gRPC-Web request to the Envoy proxy -endpoint at :8080.

  6. -
- -

What’s next

- - - -
-
- - - - - - - - - - - - diff --git a/public/docs/reference/c/client/index.html b/public/docs/reference/c/client/index.html deleted file mode 100644 index 7a1d525..0000000 --- a/public/docs/reference/c/client/index.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - C++ Client Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- -

Being familiar with these will go a long way.

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- - - - - - - - - - diff --git a/public/docs/reference/c/server/index.html b/public/docs/reference/c/server/index.html deleted file mode 100644 index 11455b6..0000000 --- a/public/docs/reference/c/server/index.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - C++ Server Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- -

Being familiar with these will go a long way.

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- - - - - - - - - - diff --git a/public/docs/reference/go/generated-code.html b/public/docs/reference/go/generated-code.html deleted file mode 100644 index 716f95d..0000000 --- a/public/docs/reference/go/generated-code.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/reference/go/generated-code/ \ No newline at end of file diff --git a/public/docs/reference/go/generated-code/index.html b/public/docs/reference/go/generated-code/index.html deleted file mode 100644 index 8fc4dfc..0000000 --- a/public/docs/reference/go/generated-code/index.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - - - – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- - -

Go Generated Code Reference

- -

This guide describes the code generated with the grpc plugin to protoc-gen-go -when compiling .proto files with protoc.

- -

You can find out how to define a gRPC service in a .proto file in Service Definitions.

- -

Thread-safety: note that client-side RPC invocations and server-side RPC handlers are thread-safe and are meant -to be run on concurrent goroutines. But also note that for individual streams, incoming and outgoing data is bi-directional but serial; -so e.g. individual streams do not support concurrent reads or concurrent writes (but reads are safely concurrent with writes). -

- -

Methods on generated server interfaces

- -

On the server side, each service Bar in the .proto file results in the function:

- -

func RegisterBarServer(s *grpc.Server, srv BarServer)

- -

The application can define a concrete implementation of the BarServer interface and register it with a grpc.Server instance -(before starting the server instance) by using this function.

- -

Unary methods

- -

These methods have the following signature on the generated service interface:

- -

Foo(context.Context, *MsgA) (*MsgB, error)

- -

In this context, MsgA is the protobuf message sent from the client, and MsgB is the protobuf message sent back from the server.

- -

Server-streaming methods

- -

These methods have the following signature on the generated service interface:

- -

Foo(*MsgA, <ServiceName>_FooServer) error

- -

In this context, MsgA is the single request from the client, and the <ServiceName>_FooServer parameter represents the server-to-client stream -of MsgB messages.

- -

<ServiceName>_FooServer has an embedded grpc.ServerStream and the following interface:

-
type <ServiceName>_FooServer interface {
-	Send(*MsgB) error
-	grpc.ServerStream
-}
-

The server-side handler can send a stream of protobuf messages to the client through this parameter’s Send method. End-of-stream for the server-to-client -stream is caused by the return of the handler method.

- -

Client-streaming methods

- -

These methods have the following signature on the generated service interface:

- -

Foo(<ServiceName>_FooServer) error

- -

In this context, <ServiceName>_FooServer can be used both to read the client-to-server message stream and to send the single server response message.

- -

<ServiceName>_FooServer has an embedded grpc.ServerStream and the following interface:

-
type <ServiceName>_FooServer interface {
-	SendAndClose(*MsgA) error
-	Recv() (*MsgB, error)
-	grpc.ServerStream
-}
-

The server-side handler can repeatedly call Recv on this parameter in order to receive the full stream of -messages from the client. Recv returns (nil, io.EOF) once it has reached the end of the stream. -The single response message from the server is sent by calling the SendAndClose method on this <ServiceName>_FooServer parameter. -Note that SendAndClose must be called once and only once.

- -

Bidi-streaming methods

- -

These methods have the following signature on the generated service interface:

- -

Foo(<ServiceName>_FooServer) error

- -

In this context, <ServiceName>_FooServer can be used to access both the client-to-server message stream and the server-to-client message stream. -<ServiceName>_FooServer has an embedded grpc.ServerStream and the following interface:

-
type <ServiceName>_FooServer interface {
-	Send(*MsgA) error
-	Recv() (*MsgB, error)
-	grpc.ServerStream
-}
-

The server-side handler can repeatedly call Recv on this parameter in order to read the client-to-server message stream. -Recv returns (nil, io.EOF) once it has reached the end of the client-to-server stream. -The response server-to-client message stream is sent by repeatedly calling the Send method of on this ServiceName>_FooServer parameter. -End-of-stream for the server-to-client stream is indicated by the return of the bidi method handler.

- -

Methods on generated client interfaces

- -

For client side usage, each service Bar in the .proto file also results in the function: func BarClient(cc *grpc.ClientConn) BarClient, which -returns a concrete implementation of the BarClient interface (this concrete implementation also lives in the generated .pb.go file).

- -

Unary Methods

- -

These methods have the following signature on the generated client stub:

- -

(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (*MsgB, error)

- -

In this context, MsgA is the single request from client to server, and MsgB contains the response sent back from the server.

- -

Server-Streaming methods

- -

These methods have the following signature on the generated client stub:

- -

Foo(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

- -

In this context, <ServiceName>_FooClient represents the server-to-client stream of MsgB messages.

- -

This stream has an embedded grpc.ClientStream and the following interface:

-
type <ServiceName>_FooClient interface {
-	Recv() (*MsgB, error)
-	grpc.ClientStream
-}
-

The stream begins when the client calls the Foo method on the stub. -The client can then repeatedly call the Recv method on the returned <ServiceName>_FooClient stream in order to read the server-to-client response stream. -This Recv method returns (nil, io.EOF) once the server-to-client stream has been completely read through.

- -

Client-Streaming methods

- -

These methods have the following signature on the generated client stub:

- -

Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

- -

In this context, <ServiceName>_FooClient represents the client-to-server stream of MsgA messages.

- -

<ServiceName>_FooClient has an embedded grpc.ClientStream and the following interface:

-
type <ServiceName>_FooClient interface {
-	Send(*MsgA) error
-	CloseAndRecv() (*MsgA, error)
-	grpc.ClientStream
-}
-

The stream begins when the client calls the Foo method on the stub. -The client can then repeatedly call the Send method on the returned <ServiceName>_FooClient stream in order to send the client-to-server message stream. -The CloseAndRecv method on this stream must be called once and only once, in order to both close the client-to-server stream -and receive the single response message from the server.

- -

Bidi-Streaming methods

- -

These methods have the following signature on the generated client stub:

- -

Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)

- -

In this context, <ServiceName>_FooClient represents both the client-to-server and server-to-client message streams.

- -

<ServiceName>_FooClient has an embedded grpc.ClientStream and the following interface:

-
type <ServiceName>_FooClient interface {
-	Send(*MsgA) error
-	Recv() (*MsgB, error)
-	grpc.ClientStream
-}
-

The stream begins when the client calls the Foo method on the stub. -The client can then repeatedly call the Send method on the returned <SericeName>_FooClient stream in order to send the -client-to-server message stream. The client can also repeatedly call Recv on this stream in order to -receive the full server-to-client message stream.

- -

End-of-stream for the server-to-client stream is indicated by a return value of (nil, io.EOF) on the Recv method of the stream. -End-of-stream for the client-to-server stream can be indicated from the client by calling the CloseSend method on the stream.

- -

Packages and Namespaces

- -

When the protoc compiler is invoked with --go_out=plugins=grpc:, the proto package to Go package translation -works the same as when the protoc-gen-go plugin is used without the grpc plugin.

- -

So, for example, if foo.proto declares itself to be in package foo, then the generated foo.pb.go file will also be in -the Go package foo.

- -
- - - - - - - - - - diff --git a/public/docs/reference/index.html b/public/docs/reference/index.html deleted file mode 100644 index 5eefbec..0000000 --- a/public/docs/reference/index.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
-

Links to the language specific automatically generated API reference documentation.

- - - - -
- - - - - - - - - - diff --git a/public/docs/reference/index.xml b/public/docs/reference/index.xml deleted file mode 100644 index a981805..0000000 --- a/public/docs/reference/index.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - Reference on gRPC - https://cjyabraham.github.io/docs/reference/ - Recent content in Reference on gRPC - Hugo -- gohugo.io - en-us - - - - - - - https://cjyabraham.github.io/docs/reference/go/generated-code/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/go/generated-code/ - Go Generated Code Reference This guide describes the code generated with the grpc plugin to protoc-gen-go when compiling .proto files with protoc. -You can find out how to define a gRPC service in a .proto file in Service Definitions. -Thread-safety: note that client-side RPC invocations and server-side RPC handlers are thread-safe and are meant to be run on concurrent goroutines. But also note that for individual streams, incoming and outgoing data is bi-directional but serial; so e. - - - - - https://cjyabraham.github.io/docs/reference/python/generated-code/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/python/generated-code/ - Python Generated Code Reference Introduction gRPC Python relies on the protocol buffers compiler (protoc) to generate code. It uses a plugin to supplement the generated code by plain protoc with gRPC-specific code. For a .proto service description containing gRPC services, the plain protoc generated code is synthesized in a _pb2.py file, and the gRPC-specifc code lands in a _grpc_pb2.py file. The latter python module imports the former. In this guide, we focus on the gRPC-specific subset of the generated code. - - - - C++ Client Reference - https://cjyabraham.github.io/docs/reference/c/client/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/c/client/ - Being familiar with these will go a long way. -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - - - - C++ Server Reference - https://cjyabraham.github.io/docs/reference/c/server/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/c/server/ - Being familiar with these will go a long way. -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - - - - Java Client Reference - https://cjyabraham.github.io/docs/reference/java/client/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/java/client/ - Java Client Reference Being familiar with these will go a long way. -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - - - - Java Generated Code Reference - https://cjyabraham.github.io/docs/reference/java/generated-code/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/java/generated-code/ - Java Generated Code Reference Packages For each service defined in a .proto file, the Java code generation produces a Java class. The class name is the service&rsquo;s name suffixed by Grpc. The package for the generated code is specified in the .proto file using the java_package option. -For example, if ServiceName is defined in a .proto file containing the following: -package grpcexample;option java_package = &#34;io.grpc.examples&#34;; Then the generated class will be io. - - - - Java Server Reference - https://cjyabraham.github.io/docs/reference/java/server/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/reference/java/server/ - Being familiar with these will go a long way. -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - - - - \ No newline at end of file diff --git a/public/docs/reference/java/client/index.html b/public/docs/reference/java/client/index.html deleted file mode 100644 index 315c448..0000000 --- a/public/docs/reference/java/client/index.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - Java Client Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- - -

Being familiar with these will go a long way.

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- - - - - - - - - - diff --git a/public/docs/reference/java/generated-code.html b/public/docs/reference/java/generated-code.html deleted file mode 100644 index cdaa707..0000000 --- a/public/docs/reference/java/generated-code.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/reference/java/generated-code/ \ No newline at end of file diff --git a/public/docs/reference/java/generated-code/index.html b/public/docs/reference/java/generated-code/index.html deleted file mode 100644 index 6458593..0000000 --- a/public/docs/reference/java/generated-code/index.html +++ /dev/null @@ -1,396 +0,0 @@ - - - - - - - - - - - - Java Generated Code Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- - -

Java Generated Code Reference

- -

Packages

- -

For each service defined in a .proto file, the Java code generation produces a -Java class. The class name is the service’s name suffixed by Grpc. The package -for the generated code is specified in the .proto file using the java_package -option.

- -

For example, if ServiceName is defined in a .proto file containing the -following:

-
package grpcexample;
-
-option java_package = "io.grpc.examples";
-

Then the generated class will be io.grpc.examples.ServiceNameGrpc.

- -

If java_package is not specified, the generated class will use the package -as specified in the .proto file. This should be avoided, as proto packages -usually do not begin with a reversed domain name.

- -

Service Stub

- -

The generated Java code contains an inner abstract class suffixed with -ImplBase, such as ServiceNameImplBase. This class defines one Java method -for each method in the service definition. It is up to the service implementer -to extend this class and implement the functionality of these methods. Without -being overridden, the methods return an error to the client saying the method is -unimplemented.

- -

The signatures of the stub methods in ServiceNameImplBase vary depending on -the type of RPCs it handles. There are four types of gRPC service methods: -unary, server-streaming, client-streaming, and bidirectional-streaming.

- -

Unary

- -

The service stub signature for a unary RPC method unaryExample:

-
public void unaryExample(
-    RequestType request,
-    StreamObserver<ResponseType> responseObserver)
-

Server-streaming

- -

The service stub signature for a server-streaming RPC method -serverStreamingExample:

-
public void serverStreamingExample(
-    RequestType request,
-    StreamObserver<ResponseType> responseObserver)
-

Notice that the signatures for unary and server-streaming RPCs are the same. A -single RequestType is received from the client, and the service implementation -sends its response(s) by invoking responseObserver.onNext(ResponseType -response).

- -

Client-streaming

- -

The service stub signature for a client-streaming RPC method -clientStreamingExample:

-
public StreamObserver<RequestType> clientStreamingExample(
-    StreamObserver<ResponseType> responseObserver)
-

Bidirectional-streaming

- -

The service stub signature for a bidirectional-streaming RPC method -bidirectionalStreamingExample:

-
public StreamObserver<RequestType> bidirectionalStreamingExample(
-    StreamObserver<ResponseType> responseObserver)
-

The signatures for client and bidirectional-streaming RPCs are the same. Since -the client can send multiple messages to the service, the service implementation -is reponsible for returning a StreamObserver<RequestType> instance. This -StreamObserver is invoked whenever additional messages are received from the -client.

- -

Client Stubs

- -

The generated class also contains stubs for use by gRPC clients to call methods -defined by the service. Each stub wraps a Channel, supplied by the user of the -generated code. The stub uses this channel to send RPCs to the service.

- -

gRPC Java generates code for three types of stubs: asynchronous, blocking, and -future. Each type of stub has a corresponding class in the generated code, such -as ServiceNameStub, ServiceNameBlockingStub, and ServiceNameFutureStub.

- -

Asynchronous Stub

- -

RPCs made via an asynchronous stub operate entirely through callbacks on -StreamObserver.

- -

The asynchronous stub contains one Java method for each method from the service -definition.

- -

A new asynchronous stub is instantiated via the ServiceNameGrpc.newStub(Channel -channel) static method.

- -

Unary

- -

The asynchronous stub signature for a unary RPC method unaryExample:

-
public void unaryExample(
-    RequestType request,
-    StreamObserver<ResponseType> responseObserver)
-

Server-streaming

- -

The asynchronous stub signature for a server-streaming RPC method -serverStreamingExample:

-
public void serverStreamingExample(
-    RequestType request,
-    StreamObserver<ResponseType> responseObserver)
-

Client-streaming

- -

The asynchronous stub signature for a client-streaming RPC method -clientStreamingExample:

-
public StreamObserver<RequestType> clientStreamingExample(
-    StreamObserver<ResponseType> responseObserver)
-

Bidirectional-streaming

- -

The asynchronous stub signature for a bidirectional-streaming RPC method -bidirectionalStreamingExample:

-
public StreamObserver<RequestType> bidirectionalStreamingExample(
-    StreamObserver<ResponseType> responseObserver)
-

Blocking Stub

- -

RPCs made through a blocking stub, as the name implies, block until the response -from the service is available.

- -

The blocking stub contains one Java method for each unary and server-streaming -method in the service definition. Blocking stubs do not support client-streaming -or bidirectional-streaming RPCs.

- -

A new blocking stub is instantiated via the -ServiceNameGrpc.newBlockingStub(Channel channel) static method.

- -

Unary

- -

The blocking stub signature for a unary RPC method unaryExample:

-
public ResponseType unaryExample(RequestType request)
-

Server-streaming

- -

The blocking stub signature for a server-streaming RPC method -serverStreamingExample:

-
public Iterator<ResponseType> serverStreamingExample(RequestType request)
-

Future Stub

- -

RPCs made via a future stub wrap the return value of the asynchronous stub in a -GrpcFuture<ResponseType>, which implements the -com.google.common.util.concurrent.ListenableFuture interface.

- -

The future stub contains one Java method for each unary method in the service -definition. Future stubs do not support streaming calls.

- -

A new future stub is instantiated via the ServiceNameGrpc.newFutureStub(Channel -channel) static method.

- -

Unary

- -

The future stub signature for a unary RPC method unaryExample:

-
public ListenableFuture<ResponseType> unaryExample(RequestType request)
-

Codegen

- -

Typically the build system handles creation of the gRPC generated code.

- -

For protobuf-based codegen, you can put your .proto files in the src/main/proto -and src/test/proto directories along with an appropriate plugin.

- -

A typical protobuf-maven-plugin configuration for generating gRPC and Protocol -Buffers code would look like the following:

-
<build>
-  <extensions>
-    <extension>
-      <groupId>kr.motd.maven</groupId>
-      <artifactId>os-maven-plugin</artifactId>
-      <version>1.4.1.Final</version>
-    </extension>
-  </extensions>
-  <plugins>
-    <plugin>
-      <groupId>org.xolstice.maven.plugins</groupId>
-      <artifactId>protobuf-maven-plugin</artifactId>
-      <version>0.5.0</version>
-      <configuration>
-        <protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact>
-        <pluginId>grpc-java</pluginId>
-        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.4.0:exe:${os.detected.classifier}</pluginArtifact>
-      </configuration>
-      <executions>
-        <execution>
-          <goals>
-            <goal>compile</goal>
-            <goal>compile-custom</goal>
-          </goals>
-        </execution>
-      </executions>
-    </plugin>
-  </plugins>
-</build>
-

Eclipse and NetBeans users should also look at os-maven-plugin’s -IDE documentation.

- -

A typical protobuf-gradle-plugin configuration would look like the following:

-
apply plugin: 'java'
-apply plugin: 'com.google.protobuf'
-
-buildscript {
-  repositories {
-    mavenCentral()
-  }
-  dependencies {
-    // ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier
-    // gradle versions
-    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
-  }
-}
-
-protobuf {
-  protoc {
-    artifact = "com.google.protobuf:protoc:3.2.0"
-  }
-  plugins {
-    grpc {
-      artifact = 'io.grpc:protoc-gen-grpc-java:1.4.0'
-    }
-  }
-  generateProtoTasks {
-    all()*.plugins {
-      grpc {}
-    }
-  }
-}
-

Bazel developers can use the -java_grpc_library -rule, typically as follows:

-
load("@grpc_java//:java_grpc_library.bzl", "java_grpc_library")
-
-proto_library(
-    name = "helloworld_proto",
-    srcs = ["src/main/proto/helloworld.proto"],
-)
-
-java_proto_library(
-    name = "helloworld_java_proto",
-    deps = [":helloworld_proto"],
-)
-
-java_grpc_library(
-    name = "helloworld_java_grpc",
-    srcs = [":helloworld_proto"],
-    deps = [":helloworld_java_proto"],
-)
-

Android developers please see this for reference.

- -

If you wish to invoke the protobuf plugin for gRPC Java directly, -the command-line syntax is as follows:

-
$ protoc --plugin=protoc-gen-grpc-java \
-  --grpc-java_out="$OUTPUT_FILE" --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE"
-
- - - - - - - - - - diff --git a/public/docs/reference/java/server/index.html b/public/docs/reference/java/server/index.html deleted file mode 100644 index 0ef0569..0000000 --- a/public/docs/reference/java/server/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - Java Server Reference – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
-

Being familiar with these will go a long way.

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- - - - - - - - - - diff --git a/public/docs/reference/python/generated-code.html b/public/docs/reference/python/generated-code.html deleted file mode 100644 index 233231a..0000000 --- a/public/docs/reference/python/generated-code.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/reference/python/generated-code/ \ No newline at end of file diff --git a/public/docs/reference/python/generated-code/index.html b/public/docs/reference/python/generated-code/index.html deleted file mode 100644 index 7e14fb0..0000000 --- a/public/docs/reference/python/generated-code/index.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - - - - - – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
- - -

Python Generated Code Reference

- -

Introduction

- -

gRPC Python relies on the protocol buffers compiler (protoc) to generate -code. It uses a plugin to supplement the generated code by plain protoc -with gRPC-specific code. For a .proto service description containing -gRPC services, the plain protoc generated code is synthesized in -a _pb2.py file, and the gRPC-specifc code lands in a _grpc_pb2.py file. -The latter python module imports the former. In this guide, we focus -on the gRPC-specific subset of the generated code.

- -

Illustrative Example

- -

Let’s look at the following FortuneTeller proto service:

-
service FortuneTeller {
-  // Returns the horoscope and zodiac sign for the given month and day.
-  rpc TellFortune(HoroscopeRequest) returns (HoroscopeResponse) {
-    // errors: invalid month or day, fortune unavailable
-  }
-
-  // Replaces the fortune for the given zodiac sign with the provided one.
-  rpc SuggestFortune(SuggestionRequest) returns (SuggestionResponse) {
-    // errors: invalid zodiac sign
-  }
-}
-

gRPC protoc plugin will synthesize code elements along the lines -of what follows in the corresponding _pb2_grpc.py file:

-
import grpc
-
-import fortune_pb2
-
-class FortuneTellerStub(object):
-
-  def __init__(self, channel):
-    """Constructor.
-
-    Args:
-      channel: A grpc.Channel.
-    """
-    self.TellFortune = channel.unary_unary(
-        '/example.FortuneTeller/TellFortune',
-        request_serializer=fortune_pb2.HoroscopeRequest.SerializeToString,
-        response_deserializer=fortune_pb2.HoroscopeResponse.FromString,
-        )
-    self.SuggestFortune = channel.unary_unary(
-        '/example.FortuneTeller/SuggestFortune',
-        request_serializer=fortune_pb2.SuggestionRequest.SerializeToString,
-        response_deserializer=fortune_pb2.SuggestionResponse.FromString,
-        )
-
-
-class FortuneTellerServicer(object):
-
-  def TellFortune(self, request, context):
-    """Returns the horoscope and zodiac sign for the given month and day.
-    errors: invalid month or day, fortune unavailable
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-  def SuggestFortune(self, request, context):
-    """Replaces the fortune for the given zodiac sign with the provided
-one.
-    errors: invalid zodiac sign
-    """
-    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-    context.set_details('Method not implemented!')
-    raise NotImplementedError('Method not implemented!')
-
-
-def add_FortuneTellerServicer_to_server(servicer, server):
-  rpc_method_handlers = {
-      'TellFortune': grpc.unary_unary_rpc_method_handler(
-          servicer.TellFortune,
-          request_deserializer=fortune_pb2.HoroscopeRequest.FromString,
-          response_serializer=fortune_pb2.HoroscopeResponse.SerializeToString,
-      ),
-      'SuggestFortune': grpc.unary_unary_rpc_method_handler(
-          servicer.SuggestFortune,
-          request_deserializer=fortune_pb2.SuggestionRequest.FromString,
-          response_serializer=fortune_pb2.SuggestionResponse.SerializeToString,
-      ),
-  }
-  generic_handler = grpc.method_handlers_generic_handler(
-      'example.FortuneTeller', rpc_method_handlers)
-  server.add_generic_rpc_handlers((generic_handler,))
-

Code Elements

- -

The gRPC generated code starts by importing the grpc package and the plain -_pb2 module, synthesized by protoc, which defines non-gRPC-specifc code -elements, like the classes corresponding to protocol buffers messages and -descriptors used by reflection.

- -

For each service Foo in the .proto file, three primary elements are -generated:

- - - -

Stub

- -

The generated Stub class is used by the gRPC clients. It -will have a constructor that takes a grpc.Channel object and initializes the -stub. For each method in the service, the initializer adds a corresponding -attribute to the stub object with the same name. Depending on the RPC type -(i.e. unary or streaming), the value of that attribute will be callable -objects of type -UnaryUnaryMultiCallable, -UnaryStreamMultiCallable, -StreamUnaryMultiCallable, -or -StreamStreamMultiCallable.

- -

Servicer

- -

For each service, a Servicer class is generated. This -class is intended to serve as the superclass of a service implementation. For -each method in the service, a corresponding function in the Servicer class -will be synthesized which is intended to be overriden in the actual service -implementation. Comments associated with code elements -in the .proto file will be transferred over as docstrings in -the generated python code.

- -

Registration Function

- -

For each service, a function will be -generated that registers a Servicer object implementing it on a grpc.Server -object, so that the server would be able to appropriately route the queries to -the respective servicer. This function takes an object that implements the -Servicer, typically an instance of a subclass of the generated Servicer -code element described above, and a -grpc.Server -object.

- -
- - - - - - - - - - diff --git a/public/docs/samples/index.html b/public/docs/samples/index.html deleted file mode 100644 index 614ca30..0000000 --- a/public/docs/samples/index.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - - Samples – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
-

Here are some sample apps to help developers build certain functionalities

- - - -
- - - - - - - - - - diff --git a/public/docs/samples/index.xml b/public/docs/samples/index.xml deleted file mode 100644 index 886ac27..0000000 --- a/public/docs/samples/index.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Samples on gRPC - https://cjyabraham.github.io/docs/samples/ - Recent content in Samples on gRPC - Hugo -- gohugo.io - en-us - - - - - - \ No newline at end of file diff --git a/public/docs/talks/index.html b/public/docs/talks/index.html deleted file mode 100644 index 4e80aa2..0000000 --- a/public/docs/talks/index.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - Presentations & Talks – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - -
-

gRPC has been talked about in many conferences and sessions. Here are a few interesting ones:

- -

-

- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -
- -
-

- -

Slides only

-

- -
- - - - - - - - - - diff --git a/public/docs/talks/index.xml b/public/docs/talks/index.xml deleted file mode 100644 index e34c285..0000000 --- a/public/docs/talks/index.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Presentations & Talks on gRPC - https://cjyabraham.github.io/docs/talks/ - Recent content in Presentations & Talks on gRPC - Hugo -- gohugo.io - en-us - - - - - - \ No newline at end of file diff --git a/public/docs/tutorials/async/docs/tutorials/async/helloasync-cpp.html b/public/docs/tutorials/async/docs/tutorials/async/helloasync-cpp.html deleted file mode 100644 index 8ea396c..0000000 --- a/public/docs/tutorials/async/docs/tutorials/async/helloasync-cpp.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/async/helloasync-cpp/ \ No newline at end of file diff --git a/public/docs/tutorials/async/helloasync-cpp/index.html b/public/docs/tutorials/async/helloasync-cpp/index.html deleted file mode 100644 index f71be0b..0000000 --- a/public/docs/tutorials/async/helloasync-cpp/index.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - - - - - - - Asynchronous Basics - C++ – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

Asynchronous Basics - C++

- - - -

This tutorial shows you how to write a simple server and client in C++ using -gRPC’s asynchronous/non-blocking APIs. It assumes you are already familiar with -writing simple synchronous gRPC code, as described in gRPC Basics: -C++. The example used in this tutorial follows on -from the basic Greeter example we used in the -overview. You’ll find it along with installation -instructions in -grpc/examples/cpp/helloworld.

- -
- -

Overview

- -

gRPC uses the -CompletionQueue -API for asynchronous operations. The basic work flow -is as follows:

- - - -

Async client

- -

To use an asynchronous client to call a remote method, you first create a -channel and stub, just as you do in a synchronous -client. Once you have your stub, you do -the following to make an asynchronous call:

- - -
    CompletionQueue cq;
-    std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
-        stub_->AsyncSayHello(&context, request, &cq));
- -
    Status status;
-    rpc->Finish(&reply, &status, (void*)1);
- -
    void* got_tag;
-    bool ok = false;
-    cq.Next(&got_tag, &ok);
-    if (ok && got_tag == (void*)1) {
-      // check reply and status
-    }
-

You can see the complete client example in -greeter_async_client.cc.

- -

Async server

- -

The server implementation requests an RPC call with a tag and then waits for the -completion queue to return the tag. The basic flow for handling an RPC -asynchronously is:

- - -
    helloworld::Greeter::AsyncService service;
-    ServerBuilder builder;
-    builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials());
-    builder.RegisterAsyncService(&service);
-    auto cq = builder.AddCompletionQueue();
-    auto server = builder.BuildAndStart();
- -
    ServerContext context;
-    HelloRequest request;
-    ServerAsyncResponseWriter<HelloReply> responder;
-    service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1);
- -
    HelloReply reply;
-    Status status;
-    void* got_tag;
-    bool ok = false;
-    cq.Next(&got_tag, &ok);
-    if (ok && got_tag == (void*)1) {
-      // set reply and status
-      responder.Finish(reply, status, (void*)2);
-    }
- -
    void* got_tag;
-    bool ok = false;
-    cq.Next(&got_tag, &ok);
-    if (ok && got_tag == (void*)2) {
-      // clean up
-    }
-

This basic flow, however, doesn’t take into account the server handling multiple -requests concurrently. To deal with this, our complete async server example uses -a CallData object to maintain the state of each RPC, and uses the address of -this object as the unique tag for the call.

-
  class CallData {
-   public:
-    // Take in the "service" instance (in this case representing an asynchronous
-    // server) and the completion queue "cq" used for asynchronous communication
-    // with the gRPC runtime.
-    CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
-        : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) {
-      // Invoke the serving logic right away.
-      Proceed();
-    }
-
-    void Proceed() {
-      if (status_ == CREATE) {
-        // As part of the initial CREATE state, we *request* that the system
-        // start processing SayHello requests. In this request, "this" acts are
-        // the tag uniquely identifying the request (so that different CallData
-        // instances can serve different requests concurrently), in this case
-        // the memory address of this CallData instance.
-        service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
-                                  this);
-        // Make this instance progress to the PROCESS state.
-        status_ = PROCESS;
-      } else if (status_ == PROCESS) {
-        // Spawn a new CallData instance to serve new clients while we process
-        // the one for this CallData. The instance will deallocate itself as
-        // part of its FINISH state.
-        new CallData(service_, cq_);
-
-        // The actual processing.
-        std::string prefix("Hello ");
-        reply_.set_message(prefix + request_.name());
-
-        // And we are done! Let the gRPC runtime know we've finished, using the
-        // memory address of this instance as the uniquely identifying tag for
-        // the event.
-        responder_.Finish(reply_, Status::OK, this);
-        status_ = FINISH;
-      } else {
-        GPR_ASSERT(status_ == FINISH);
-        // Once in the FINISH state, deallocate ourselves (CallData).
-        delete this;
-      }
-    }
-  }
-

For simplicity the server only uses one completion queue for all events, and -runs a main loop in HandleRpcs to query the queue:

-
  void HandleRpcs() {
-    // Spawn a new CallData instance to serve new clients.
-    new CallData(&service_, cq_.get());
-    void* tag;  // uniquely identifies a request.
-    bool ok;
-    while (true) {
-      // Block waiting to read the next event from the completion queue. The
-      // event is uniquely identified by its tag, which in this case is the
-      // memory address of a CallData instance.
-      cq_->Next(&tag, &ok);
-      GPR_ASSERT(ok);
-      static_cast<CallData*>(tag)->Proceed();
-    }
-  }
-

Shutting Down the Server

- -

We’ve been using a completion queue to get the async notifications. Care must be -taken to shut it down after the server has also been shut down.

- -

Remember we got our completion queue instance cq_ in ServerImpl::Run() by -running cq_ = builder.AddCompletionQueue(). Looking at -ServerBuilder::AddCompletionQueue’s documentation we see that

- -
-

… Caller is required to shutdown the server prior to shutting down the -returned completion queue.

-
- -

Refer to ServerBuilder::AddCompletionQueue’s full docstring for more details. -What this means in our example is that ServerImpl's destructor looks like:

-
  ~ServerImpl() {
-    server_->Shutdown();
-    // Always shutdown the completion queue after the server.
-    cq_->Shutdown();
-  }
-

You can see our complete server example in -greeter_async_server.cc.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/auth/oauth2-objective-c.html b/public/docs/tutorials/auth/oauth2-objective-c.html deleted file mode 100644 index b7f00d8..0000000 --- a/public/docs/tutorials/auth/oauth2-objective-c.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/auth/oauth2-objective-c/ \ No newline at end of file diff --git a/public/docs/tutorials/auth/oauth2-objective-c/index.html b/public/docs/tutorials/auth/oauth2-objective-c/index.html deleted file mode 100644 index cb3f644..0000000 --- a/public/docs/tutorials/auth/oauth2-objective-c/index.html +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - - - - - - - OAuth2 on gRPC - Objective-C – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

OAuth2 on gRPC - Objective-C

- - - -

This example demonstrates how to use OAuth2 on gRPC to make -authenticated API calls on behalf of a user.

- -

By walking through it you’ll also learn how to use the Objective-C gRPC API to:

- - - -

It assumes you know the basics on how to make gRPC API calls using the -Objective-C client library, as shown in gRPC Basics: -Objective-C and the -overview, and are familiar with OAuth2 concepts like access -token.

- -
- -

- -

Example code and setup

- -

The example code for our tutorial is in -gprc/examples/objective-c/auth_sample. To -download the example, clone this repository by running the following commands:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ cd grpc
-$ git submodule update --init
-

Then change your current directory to examples/objective-c/auth_sample:

-
$ cd examples/objective-c/auth_sample
-

Our example is a simple application with two views. The first view lets a user -sign in and out using the OAuth2 flow of Google’s iOS SignIn -library. (Google’s library -is used in this example because the test gRPC service we are going to call -expects Google account credentials, but neither gRPC nor the Objective-C client -library is tied to any specific OAuth2 provider). The second view makes a gRPC -request to the test server, using the access token obtained by the first view.

- -

Note: OAuth2 libraries need the application to register and obtain an ID from -the identity provider (in the case of this example app, Google). The app’s XCode -project is configured using that ID, so you shouldn’t copy this project “as is” -for your own app: it would result in your app being identified in the consent -screen as “gRPC-AuthSample”, and not having access to real Google services. -Instead, configure your own XCode project following the instructions -here.

- -

As with the other Objective-C examples, you also should have -Cocoapods installed, as well as the relevant -tools to generate the client library code. You can obtain the latter by -following these setup instructions.

- -

- -

Try it out!

- -

To try the sample app, first have Cocoapods generate and install the client library for our .proto -files:

-
$ pod install
-

(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods -doesn’t have it yet on your computer’s cache).

- -

Finally, open the XCode workspace created by Cocoapods, and run the app.

- -

The first view, SelectUserViewController.h/m, asks you to sign in with your -Google account, and to give the “gRPC-AuthSample” app the following permissions:

- - - -

This last permission, corresponding to the scope -https://www.googleapis.com/auth/xapi.zoo doesn’t grant any real capability: -it’s only used for testing. You can log out at any time.

- -

The second view, MakeRPCViewController.h/m, makes a gRPC request to a test -server at https://grpc-test.sandbox.google.com, sending the access token along -with the request. The test service simply validates the token and writes in its -response which user it belongs to, and which scopes it gives access to. (The -client application already knows those two values; it’s a way to verify that -everything went as expected).

- -

The next sections guide you step-by-step through how the gRPC call in -MakeRPCViewController is performed. You can see the complete code in -MakeRPCViewController.m.

- -

- -

Create an RPC object

- -

The other basic tutorials show how to invoke an RPC by calling an asynchronous -method in a generated client object. However, to make an authenticated call you -need to initialize an object that represents the RPC, and configure it before -starting the network request. First let’s look at how to create the RPC object.

- -

Assume you have a proto service definition like this:

-
option objc_class_prefix = "AUTH";
-
-service TestService {
-  rpc UnaryCall(Request) returns (Response);
-}
-

A unaryCallWithRequest:handler: method, with which you’re already familiar, is -generated for the AUTHTestService class:

-
[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) {
-  ...
-}];
-

In addition, an RPCToUnaryCallWithRequest:handler: method is generated, which returns a -not-yet-started RPC object:

-
#import <ProtoRPC/ProtoRPC.h>
-
-ProtoRPC *call =
-    [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) {
-      ...
-    }];
-

You can start the RPC represented by this object at any later time like this:

-
[call start];
-

- -

Setting request metadata: Auth header with an access token

- -

Now let’s look at how to configure some settings on the RPC object. The -ProtoRPC class has a requestHeaders property (inherited from GRPCCall) -defined like this:

-
@property(atomic, readonly) id<GRPCRequestHeaders> requestHeaders
-

You can think of the GRPCRequestHeaders protocol as equivalent to the -NSMutableDictionary class. Setting elements of this dictionary of metadata -keys and values means this metadata will be sent on the wire when the call is -started. gRPC metadata are pieces of information about the call sent by the -client to the server (and vice versa). They take the form of key-value pairs and -are essentially opaque to gRPC itself.

- -

For convenience, the property is initialized with an empty -NSMutableDictionary, so that request metadata elements can be set like this:

-
call.requestHeaders[@"My-Header"] = @"Value for this header";
-call.requestHeaders[@"Another-Header"] = @"Its value";
-

A typical use of metadata is for authentication details, as in our example. If -you have an access token, OAuth2 specifies it is to be sent in this format:

-
call.requestHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken];
-

- -

Getting response metadata: Auth challenge header

- -

The ProtoRPC class also inherits a pair of properties, responseHeaders and -responseTrailers, analogous to the request metadata we just looked at but sent -back by the server to the client. They are defined like this:

-
@property(atomic, readonly) NSDictionary *responseHeaders;
-@property(atomic, readonly) NSDictionary *responseTrailers;
-

In OAuth2, if there’s an authentication error the server will send back a -challenge header. This is returned in the RPC’s response headers. To access -this, as in our example’s error-handling code, you write:

-
call.responseHeaders[@"www-authenticate"]
-

Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), -the keys of the response metadata are always ASCII strings in lowercase.

- -

Many uses cases of response metadata involve getting more details about an RPC -error. For convenience, when a NSError instance is passed to an RPC handler -block, the response headers and trailers dictionaries can also be accessed this -way:

-
error.userInfo[kGRPCHeadersKey] == call.responseHeaders
-error.userInfo[kGRPCTrailersKey] == call.responseTrailers
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/android.html b/public/docs/tutorials/basic/android.html deleted file mode 100644 index 77f2612..0000000 --- a/public/docs/tutorials/basic/android.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/android/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/android/index.html b/public/docs/tutorials/basic/android/index.html deleted file mode 100644 index 834b6fa..0000000 --- a/public/docs/tutorials/basic/android/index.html +++ /dev/null @@ -1,468 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Android Java – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Android Java

- - - -

This tutorial provides a basic Android Java programmer’s introduction to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar with protocol buffers. -This guide also does not cover anything on the server side. You can check the Java guide for more information.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients.

- -

With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC’s supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating.

- -

Example code and setup

- -

The example code for our tutorial is in grpc-java’s examples/android. To download the example, clone the grpc-java repository by running the following command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc-java.git
-

Then change your current directory to grpc-java/examples/android:

-
$ cd grpc-java/examples/android
-

You also should have the relevant tools installed to generate the client interface code - if you don’t already, follow the setup instructions in the Java README.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to define the gRPC service and the method request and response types using protocol buffers. You can see the complete .proto file in routeguide/app/src/main/proto/route_guide.proto.

- -

As we’re generating Java code in this example, we’ve specified a java_package file option in our .proto:

-
option java_package = "io.grpc.examples";
-

This specifies the package we want to use for our generated Java classes. If no explicit java_package option is given in the .proto file, then by default the proto package (specified using the “package” keyword) will be used. However, proto packages generally do not make good Java packages since proto packages are not expected to start with reverse domain names. If we generate code in another language from this .proto, the java_package option has no effect.

- -

To define a service, we specify a named service in the .proto file:

-
service RouteGuide {
-   ...
-}
-

Then we define rpc methods inside our service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here’s the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client code

- -

Next we need to generate the gRPC client interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special gRPC Java plugin. You need to use the -proto3 compiler (which supports -both proto2 and proto3 syntax) in order to generate gRPC services.

- -

The build system for this example is also part of Java gRPC itself’s build. You -can refer to the README and -build.gradle for -how to generate code from your own .proto files. -Note that for Android, we will use protobuf lite which is optimized for mobile usecase.

- -

The following classes are generated from our service definition:

- - - -

Creating the client

- -

In this section, we’ll look at creating a Java client for our RouteGuide service. You can see our complete example client code in routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideActivity.java.

- -

Creating a stub

- -

To call service methods, we first need to create a stub, or rather, two stubs:

- - - -

First we need to create a gRPC channel for our stub, specifying the server address and port we want to connect to: -We use a ManagedChannelBuilder to create the channel.

-
mChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
-

Now we can use the channel to create our stubs using the newStub and newBlockingStub methods provided in the RouteGuideGrpc class we generated from our .proto.

-
blockingStub = RouteGuideGrpc.newBlockingStub(mChannel);
-asyncStub = RouteGuideGrpc.newStub(mChannel);
-

Calling service methods

- -

Now let’s look at how we call our service methods.

- -
Simple RPC
- -

Calling the simple RPC GetFeature on the blocking stub is as straightforward as calling a local method.

-
Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
-Feature feature = blockingStub.getFeature(request);
-

We create and populate a request protocol buffer object (in our case Point), pass it to the getFeature() method on our blocking stub, and get back a Feature.

- -
Server-side streaming RPC
- -

Next, let’s look at a server-side streaming call to ListFeatures, which returns a stream of geographical Features:

-
Rectangle request =
-    Rectangle.newBuilder()
-        .setLo(Point.newBuilder().setLatitude(lowLat).setLongitude(lowLon).build())
-        .setHi(Point.newBuilder().setLatitude(hiLat).setLongitude(hiLon).build()).build();
-Iterator<Feature> features = blockingStub.listFeatures(request);
-

As you can see, it’s very similar to the simple RPC we just looked at, except instead of returning a single Feature, the method returns an Iterator that the client can use to read all the returned Features.

- -
Client-side streaming RPC
- -

Now for something a little more complicated: the client-side streaming method RecordRoute, where we send a stream of Points to the server and get back a single RouteSummary. For this method we need to use the asynchronous stub. If you’ve already read Creating the server some of this may look very familiar - asynchronous streaming RPCs are implemented in a similar way on both sides.

-
private String recordRoute(List<Point> points, int numPoints, RouteGuideStub asyncStub)
-        throws InterruptedException, RuntimeException {
-    final StringBuffer logs = new StringBuffer();
-    appendLogs(logs, "*** RecordRoute");
-
-    final CountDownLatch finishLatch = new CountDownLatch(1);
-    StreamObserver<RouteSummary> responseObserver = new StreamObserver<RouteSummary>() {
-        @Override
-        public void onNext(RouteSummary summary) {
-            appendLogs(logs, "Finished trip with {0} points. Passed {1} features. "
-                    + "Travelled {2} meters. It took {3} seconds.", summary.getPointCount(),
-                    summary.getFeatureCount(), summary.getDistance(),
-                    summary.getElapsedTime());
-        }
-
-        @Override
-        public void onError(Throwable t) {
-            failed = t;
-            finishLatch.countDown();
-        }
-
-        @Override
-        public void onCompleted() {
-            appendLogs(logs, "Finished RecordRoute");
-            finishLatch.countDown();
-        }
-    };
-
-    StreamObserver<Point> requestObserver = asyncStub.recordRoute(responseObserver);
-    try {
-        // Send numPoints points randomly selected from the points list.
-        Random rand = new Random();
-        for (int i = 0; i < numPoints; ++i) {
-            int index = rand.nextInt(points.size());
-            Point point = points.get(index);
-            appendLogs(logs, "Visiting point {0}, {1}", RouteGuideUtil.getLatitude(point),
-                    RouteGuideUtil.getLongitude(point));
-            requestObserver.onNext(point);
-            // Sleep for a bit before sending the next one.
-            Thread.sleep(rand.nextInt(1000) + 500);
-            if (finishLatch.getCount() == 0) {
-                // RPC completed or errored before we finished sending.
-                // Sending further requests won't error, but they will just be thrown away.
-                break;
-            }
-        }
-    } catch (RuntimeException e) {
-        // Cancel RPC
-        requestObserver.onError(e);
-        throw e;
-    }
-    // Mark the end of requests
-    requestObserver.onCompleted();
-
-    // Receiving happens asynchronously
-    if (!finishLatch.await(1, TimeUnit.MINUTES)) {
-        throw new RuntimeException(
-               "Could not finish rpc within 1 minute, the server is likely down");
-    }
-
-    if (failed != null) {
-        throw new RuntimeException(failed);
-    }
-    return logs.toString();
-}
-

As you can see, to call this method we need to create a StreamObserver, which implements a special interface for the server to call with its RouteSummary response. In our StreamObserver we:

- - - -

We then pass the StreamObserver to the asynchronous stub’s recordRoute() method and get back our own StreamObserver request observer to write our Points to send to the server. Once we’ve finished writing points, we use the request observer’s onCompleted() method to tell gRPC that we’ve finished writing on the client side. Once we’re done, we check our SettableFuture to check that the server has completed on its side.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
private String routeChat(RouteGuideStub asyncStub) throws InterruptedException,
-        RuntimeException {
-    final StringBuffer logs = new StringBuffer();
-    appendLogs(logs, "*** RouteChat");
-    final CountDownLatch finishLatch = new CountDownLatch(1);
-    StreamObserver<RouteNote> requestObserver =
-            asyncStub.routeChat(new StreamObserver<RouteNote>() {
-                @Override
-                public void onNext(RouteNote note) {
-                    appendLogs(logs, "Got message \"{0}\" at {1}, {2}", note.getMessage(),
-                            note.getLocation().getLatitude(),
-                            note.getLocation().getLongitude());
-                }
-
-                @Override
-                public void onError(Throwable t) {
-                    failed = t;
-                    finishLatch.countDown();
-                }
-
-                @Override
-                public void onCompleted() {
-                    appendLogs(logs,"Finished RouteChat");
-                    finishLatch.countDown();
-                }
-            });
-
-    try {
-        RouteNote[] requests =
-                {newNote("First message", 0, 0), newNote("Second message", 0, 1),
-                        newNote("Third message", 1, 0), newNote("Fourth message", 1, 1)};
-
-        for (RouteNote request : requests) {
-            appendLogs(logs, "Sending message \"{0}\" at {1}, {2}", request.getMessage(),
-                    request.getLocation().getLatitude(),
-                    request.getLocation().getLongitude());
-            requestObserver.onNext(request);
-        }
-    } catch (RuntimeException e) {
-        // Cancel RPC
-        requestObserver.onError(e);
-        throw e;
-    }
-    // Mark the end of requests
-    requestObserver.onCompleted();
-
-    // Receiving happens asynchronously
-    if (!finishLatch.await(1, TimeUnit.MINUTES)) {
-        throw new RuntimeException(
-                "Could not finish rpc within 1 minute, the server is likely down");
-    }
-
-    if (failed != null) {
-        throw new RuntimeException(failed);
-    }
-
-    return logs.toString();
-}
-

As with our client-side streaming example, we both get and return a StreamObserver response observer, except this time we send values via our method’s response observer while the server is still writing messages to their message stream. The syntax for reading and writing here is exactly the same as for our client-streaming method. Although each side will always get the other’s messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently.

- -

Try it out!

- -

Follow the instructions in the example directory README to build and run the client and server.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/c.html b/public/docs/tutorials/basic/c.html deleted file mode 100644 index f8c71ec..0000000 --- a/public/docs/tutorials/basic/c.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/c/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/c/index.html b/public/docs/tutorials/basic/c/index.html deleted file mode 100644 index f5ba110..0000000 --- a/public/docs/tutorials/basic/c/index.html +++ /dev/null @@ -1,639 +0,0 @@ - - - - - - - - - - - - gRPC Basics - C++ – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - C++

- - - -

This tutorial provides a basic C++ programmer’s introduction to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol -buffers. Note -that the example in this tutorial uses the proto3 version of the protocol -buffers language: you can find out more in -the proto3 language -guide and C++ -generated code -guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/cpp/route_guide. To -download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-

Then change your current directory to examples/cpp/route_guide:

-
$ cd examples/cpp/route_guide
-

You also should have the relevant tools installed to generate the server and -client interface code - if you don’t already, follow the setup instructions in -the C++ quick start guide.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol buffers. -You can see the complete .proto file in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special gRPC C++ plugin.

- -

For simplicity, we’ve provided a Makefile -that runs protoc for you with the appropriate plugin, input, and output (if -you want to run this yourself, make sure you’ve installed protoc and followed -the gRPC code installation instructions first):

-
$ make route_guide.grpc.pb.cc route_guide.pb.cc
-

which actually runs:

-
$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto
-$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto
-

Running this command generates the following files in your current directory:

- - - -

These contain:

- - - -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job:

- - - -

You can find our example RouteGuide server in -examples/cpp/route_guide/route_guide_server.cc. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a RouteGuideImpl class that implements the -generated RouteGuide::Service interface:

-
class RouteGuideImpl final : public RouteGuide::Service {
-...
-}
-
-

In this case we’re implementing the synchronous version of RouteGuide, which -provides our default gRPC server behaviour. It’s also possible to implement an -asynchronous interface, RouteGuide::AsyncService, which allows you to further -customize your server’s threading behaviour, though we won’t look at this in -this tutorial.

- -

RouteGuideImpl implements all our service methods. Let’s look at the simplest -type first, GetFeature, which just gets a Point from the client and returns -the corresponding feature information from its database in a Feature.

-
Status GetFeature(ServerContext* context, const Point* point,
-                  Feature* feature) override {
-  feature->set_name(GetFeatureName(*point, feature_list_));
-  feature->mutable_location()->CopyFrom(*point);
-  return Status::OK;
-}
-
-

The method is passed a context object for the RPC, the client’s Point protocol -buffer request, and a Feature protocol buffer to fill in with the response -information. In the method we populate the Feature with the appropriate -information, and then return with an OK status to tell gRPC that we’ve -finished dealing with the RPC and that the Feature can be returned to the -client.

- -

Note that all service methods can (and will!) be called from multiple threads at -the same time. You have to make sure that your method implementations are -thread safe. In our example, feature_list_ is never changed after -construction, so it is safe by design. But if feature_list_ would change during -the lifetime of the service, we would need to synchronize access to this member.

- -

Now let’s look at something a bit more complicated - a streaming RPC. -ListFeatures is a server-side streaming RPC, so we need to send back multiple -Features to our client.

-
Status ListFeatures(ServerContext* context, const Rectangle* rectangle,
-                    ServerWriter<Feature>* writer) override {
-  auto lo = rectangle->lo();
-  auto hi = rectangle->hi();
-  long left = std::min(lo.longitude(), hi.longitude());
-  long right = std::max(lo.longitude(), hi.longitude());
-  long top = std::max(lo.latitude(), hi.latitude());
-  long bottom = std::min(lo.latitude(), hi.latitude());
-  for (const Feature& f : feature_list_) {
-    if (f.location().longitude() >= left &&
-        f.location().longitude() <= right &&
-        f.location().latitude() >= bottom &&
-        f.location().latitude() <= top) {
-      writer->Write(f);
-    }
-  }
-  return Status::OK;
-}
-
-

As you can see, instead of getting simple request and response objects in our -method parameters, this time we get a request object (the Rectangle in which -our client wants to find Features) and a special ServerWriter object. In the -method, we populate as many Feature objects as we need to return, writing them -to the ServerWriter using its Write() method. Finally, as in our simple RPC, -we return Status::OK to tell gRPC that we’ve finished writing responses.

- -

If you look at the client-side streaming method RecordRoute you’ll see it’s -quite similar, except this time we get a ServerReader instead of a request -object and a single response. We use the ServerReaders Read() method to -repeatedly read in our client’s requests to a request object (in this case a -Point) until there are no more messages: the server needs to check the return -value of Read() after each call. If true, the stream is still good and it -can continue reading; if false the message stream has ended.

-
while (stream->Read(&point)) {
-  ...//process client input
-}
-
-

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
Status RouteChat(ServerContext* context,
-                 ServerReaderWriter<RouteNote, RouteNote>* stream) override {
-  std::vector<RouteNote> received_notes;
-  RouteNote note;
-  while (stream->Read(&note)) {
-    for (const RouteNote& n : received_notes) {
-      if (n.location().latitude() == note.location().latitude() &&
-          n.location().longitude() == note.location().longitude()) {
-        stream->Write(n);
-      }
-    }
-    received_notes.push_back(note);
-  }
-
-  return Status::OK;
-}
-
-

This time we get a ServerReaderWriter that can be used to read and write -messages. The syntax for reading and writing here is exactly the same as for our -client-streaming and server-streaming methods. Although each side will always -get the other’s messages in the order they were written, both the client and -server can read and write in any order — the streams operate completely -independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
void RunServer(const std::string& db_path) {
-  std::string server_address("0.0.0.0:50051");
-  RouteGuideImpl service(db_path);
-
-  ServerBuilder builder;
-  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
-  builder.RegisterService(&service);
-  std::unique_ptr<Server> server(builder.BuildAndStart());
-  std::cout << "Server listening on " << server_address << std::endl;
-  server->Wait();
-}
-
-

As you can see, we build and start our server using a ServerBuilder. To do this, we:

- -
    -
  1. Create an instance of our service implementation class RouteGuideImpl.
  2. -
  3. Create an instance of the factory ServerBuilder class.
  4. -
  5. Specify the address and port we want to use to listen for client requests -using the builder’s AddListeningPort() method.
  6. -
  7. Register our service implementation with the builder.
  8. -
  9. Call BuildAndStart() on the builder to create and start an RPC server for -our service.
  10. -
  11. Call Wait() on the server to do a blocking wait until process is killed or -Shutdown() is called.
  12. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a C++ client for our RouteGuide -service. You can see our complete example client code in -examples/cpp/route_guide/route_guide_client.cc.

- -

Creating a stub

- -

To call service methods, we first need to create a stub.

- -

First we need to create a gRPC channel for our stub, specifying the server -address and port we want to connect to - in our case we’ll use no SSL:

-
grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
-
-

Note: In order to set additional options for the channel, use the grpc::CreateCustomChannel() api with any special channel arguments - grpc::ChannelArguments

- -

Now we can use the channel to create our stub using the NewStub method provided in the RouteGuide class we generated from our .proto.

-
public:
- RouteGuideClient(std::shared_ptr<ChannelInterface> channel,
-                  const std::string& db)
-     : stub_(RouteGuide::NewStub(channel)) {
-   ...
- }
-
-

Calling service methods

- -

Now let’s look at how we call our service methods. Note that in this tutorial -we’re calling the blocking/synchronous versions of each method: this means -that the RPC call waits for the server to respond, and will either return a -response or raise an exception.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local method.

-
Point point;
-Feature feature;
-point = MakePoint(409146138, -746188906);
-GetOneFeature(point, &feature);
-
-...
-
-bool GetOneFeature(const Point& point, Feature* feature) {
-  ClientContext context;
-  Status status = stub_->GetFeature(&context, point, feature);
-  ...
-}
-
-

As you can see, we create and populate a request protocol buffer object (in our -case Point), and create a response protocol buffer object for the server to -fill in. We also create a ClientContext object for our call - you can -optionally set RPC configuration values on this object, such as deadlines, -though for now we’ll use the default settings. Note that you cannot reuse this -object between calls. Finally, we call the method on the stub, passing it the -context, request, and response. If the method returns OK, then we can read the -response information from the server from our response object.

-
std::cout << "Found feature called " << feature->name()  << " at "
-          << feature->location().latitude()/kCoordFactor_ << ", "
-          << feature->location().longitude()/kCoordFactor_ << std::endl;
-
-
Streaming RPCs
- -

Now let’s look at our streaming methods. If you’ve already read Creating the -server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides. Here’s where we call the server-side -streaming method ListFeatures, which returns a stream of geographical -Features:

-
std::unique_ptr<ClientReader<Feature> > reader(
-    stub_->ListFeatures(&context, rect));
-while (reader->Read(&feature)) {
-  std::cout << "Found feature called "
-            << feature.name() << " at "
-            << feature.location().latitude()/kCoordFactor_ << ", "
-            << feature.location().longitude()/kCoordFactor_ << std::endl;
-}
-Status status = reader->Finish();
-
-

Instead of passing the method a context, request, and response, we pass it a -context and request and get a ClientReader object back. The client can use the -ClientReader to read the server’s responses. We use the ClientReaders -Read() method to repeatedly read in the server’s responses to a response -protocol buffer object (in this case a Feature) until there are no more -messages: the client needs to check the return value of Read() after each -call. If true, the stream is still good and it can continue reading; if -false the message stream has ended. Finally, we call Finish() on the stream -to complete the call and get our RPC status.

- -

The client-side streaming method RecordRoute is similar, except there we pass -the method a context and response object and get back a ClientWriter.

-
std::unique_ptr<ClientWriter<Point> > writer(
-    stub_->RecordRoute(&context, &stats));
-for (int i = 0; i < kPoints; i++) {
-  const Feature& f = feature_list_[feature_distribution(generator)];
-  std::cout << "Visiting point "
-            << f.location().latitude()/kCoordFactor_ << ", "
-            << f.location().longitude()/kCoordFactor_ << std::endl;
-  if (!writer->Write(f.location())) {
-    // Broken stream.
-    break;
-  }
-  std::this_thread::sleep_for(std::chrono::milliseconds(
-      delay_distribution(generator)));
-}
-writer->WritesDone();
-Status status = writer->Finish();
-if (status.IsOk()) {
-  std::cout << "Finished trip with " << stats.point_count() << " points\n"
-            << "Passed " << stats.feature_count() << " features\n"
-            << "Travelled " << stats.distance() << " meters\n"
-            << "It took " << stats.elapsed_time() << " seconds"
-            << std::endl;
-} else {
-  std::cout << "RecordRoute rpc failed." << std::endl;
-}
-
-

Once we’ve finished writing our client’s requests to the stream using Write(), -we need to call WritesDone() on the stream to let gRPC know that we’ve -finished writing, then Finish() to complete the call and get our RPC status. -If the status is OK, our response object that we initially passed to -RecordRoute() will be populated with the server’s response.

- -

Finally, let’s look at our bidirectional streaming RPC RouteChat(). In this -case, we just pass a context to the method and get back a ClientReaderWriter, -which we can use to both write and read messages.

-
std::shared_ptr<ClientReaderWriter<RouteNote, RouteNote> > stream(
-    stub_->RouteChat(&context));
-
-

The syntax for reading and writing here is exactly the same as for our -client-streaming and server-streaming methods. Although each side will always -get the other’s messages in the order they were written, both the client and -server can read and write in any order — the streams operate completely -independently.

- -

Try it out!

- -

Build client and server:

-
$ make
-

Run the server, which will listen on port 50051:

-
$ ./route_guide_server
-

Run the client (in a different terminal):

-
$ ./route_guide_client
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/csharp.html b/public/docs/tutorials/basic/csharp.html deleted file mode 100644 index 46d5e63..0000000 --- a/public/docs/tutorials/basic/csharp.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/csharp/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/csharp/index.html b/public/docs/tutorials/basic/csharp/index.html deleted file mode 100644 index 2b3671a..0000000 --- a/public/docs/tutorials/basic/csharp/index.html +++ /dev/null @@ -1,636 +0,0 @@ - - - - - - - - - - - - gRPC Basics - C# – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - C#

- - - -

This tutorial provides a basic C# programmer’s introduction to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol buffers. Note that the -example in this tutorial uses the proto3 version of the protocol buffers -language: you can find out more in the -proto3 language guide and -C# generated code reference.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/csharp/RouteGuide. To -download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ cd grpc
-

All the files for this tutorial are in the directory -examples/csharp/RouteGuide. Open the solution -examples/csharp/RouteGuide/RouteGuide.sln from Visual Studio (Windows or Mac) or Visual Studio Code. -For additional installation details, see the How to use -instructions.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol buffers. -You can see the complete .proto file in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. This can be done by invoking the protocol buffer compiler protoc with -a special gRPC C# plugin from the command line, but starting from version -1.17 the Grpc.Tools NuGet package integrates with MSBuild to provide automatic C# code generation -from .proto files, which gives much better developer experience by running -the right commands for you as part of the build.

- -

This example already has a dependency on Grpc.Tools NuGet package and the -route_guide.proto has already been added to the project, so the only thing -needed to generate the client and server code is to build the solution. -That can be done by running dotnet build RouteGuide.sln or building directly -in Visual Studio.

- -

The build regenerates the following files -under the RouteGuide/obj/Debug/TARGET_FRAMEWORK directory:

- - - -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job:

- - - -

You can find our example RouteGuide server in -examples/csharp/RouteGuide/RouteGuideServer/RouteGuideImpl.cs. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a RouteGuideImpl class that inherits from the -generated RouteGuide.RouteGuideBase:

-
// RouteGuideImpl provides an implementation of the RouteGuide service.
-public class RouteGuideImpl : RouteGuide.RouteGuideBase
-
-
Simple RPC
- -

RouteGuideImpl implements all our service methods. Let’s look at the simplest -type first, GetFeature, which just gets a Point from the client and returns -the corresponding feature information from its database in a Feature.

-
public override Task<Feature> GetFeature(Point request, Grpc.Core.ServerCallContext context)
-{
-    return Task.FromResult(CheckFeature(request));
-}
-
-

The method is passed a context for the RPC (which is empty in the alpha -release), the client’s Point protocol buffer request, and returns a Feature -protocol buffer. In the method we create the Feature with the appropriate -information, and then return it. To allow asynchronous implementation, the -method returns Task<Feature> rather than just Feature. You are free to -perform your computations synchronously and return the result once you’ve -finished, just as we do in the example.

- -
Server-side streaming RPC
- -

Now let’s look at something a bit more complicated - a streaming RPC. -ListFeatures is a server-side streaming RPC, so we need to send back multiple -Feature protocol buffers to our client.

-
// in RouteGuideImpl
-public override async Task ListFeatures(Rectangle request,
-    Grpc.Core.IServerStreamWriter<Feature> responseStream,
-    Grpc.Core.ServerCallContext context)
-{
-    var responses = features.FindAll( (feature) => feature.Exists() && request.Contains(feature.Location) );
-    foreach (var response in responses)
-    {
-        await responseStream.WriteAsync(response);
-    }
-}
-
-

As you can see, here the request object is a Rectangle in which our client -wants to find Features, but instead of returning a simple response we need to -write responses to an asynchronous stream IServerStreamWriter using async -method WriteAsync.

- -
Client-side streaming RPC
- -

Similarly, the client-side streaming method RecordRoute uses an -IAsyncEnumerator, -to read the stream of requests using the async method MoveNext and the -Current property.

-
public override async Task<RouteSummary> RecordRoute(Grpc.Core.IAsyncStreamReader<Point> requestStream,
-    Grpc.Core.ServerCallContext context)
-{
-    int pointCount = 0;
-    int featureCount = 0;
-    int distance = 0;
-    Point previous = null;
-    var stopwatch = new Stopwatch();
-    stopwatch.Start();
-
-    while (await requestStream.MoveNext())
-    {
-        var point = requestStream.Current;
-        pointCount++;
-        if (CheckFeature(point).Exists())
-        {
-            featureCount++;
-        }
-        if (previous != null)
-        {
-            distance += (int) previous.GetDistance(point);
-        }
-        previous = point;
-    }
-
-    stopwatch.Stop();
-
-    return new RouteSummary
-    {
-        PointCount = pointCount,
-        FeatureCount = featureCount,
-        Distance = distance,
-        ElapsedTime = (int)(stopwatch.ElapsedMilliseconds / 1000)
-    };
-}
-
-
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat.

-
public override async Task RouteChat(Grpc.Core.IAsyncStreamReader<RouteNote> requestStream,
-    Grpc.Core.IServerStreamWriter<RouteNote> responseStream,
-    Grpc.Core.ServerCallContext context)
-{
-    while (await requestStream.MoveNext())
-    {
-        var note = requestStream.Current;
-        List<RouteNote> prevNotes = AddNoteForLocation(note.Location, note);
-        foreach (var prevNote in prevNotes)
-        {
-            await responseStream.WriteAsync(prevNote);
-        }
-    }
-}
-
-

Here the method receives both requestStream and responseStream arguments. -Reading the requests is done the same way as in the client-side streaming method -RecordRoute. Writing the responses is done the same way as in the server-side -streaming method ListFeatures.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile);
-
-Server server = new Server
-{
-    Services = { RouteGuide.BindService(new RouteGuideImpl(features)) },
-    Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
-};
-server.Start();
-
-Console.WriteLine("RouteGuide server listening on port " + port);
-Console.WriteLine("Press any key to stop the server...");
-Console.ReadKey();
-
-server.ShutdownAsync().Wait();
-
-

As you can see, we build and start our server using Grpc.Core.Server class. To -do this, we:

- -
    -
  1. Create an instance of Grpc.Core.Server.
  2. -
  3. Create an instance of our service implementation class RouteGuideImpl.
  4. -
  5. Register our service implementation by adding its service definition to the -Services collection (We obtain the service definition from the generated -RouteGuide.BindService method).
  6. -
  7. Specify the address and port we want to use to listen for client requests. -This is done by adding ServerPort to the Ports collection.
  8. -
  9. Call Start on the server instance to start an RPC server for our service.
  10. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a C# client for our RouteGuide -service. You can see our complete example client code in -examples/csharp/RouteGuide/RouteGuideClient/Program.cs.

- -

Creating a client object

- -

To call service methods, we first need to create a client object (also referred -to as stub for other gRPC languages).

- -

First, we need to create a gRPC client channel that will connect to gRPC server. -Then, we create an instance of the RouteGuite.RouteGuideClient class generated -from our .proto, passing the channel as an argument.

-
Channel channel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure);
-var client = new RouteGuide.RouteGuideClient(channel);
-
-// YOUR CODE GOES HERE
-
-channel.ShutdownAsync().Wait();
-
-

Calling service methods

- -

Now let’s look at how we call our service methods. gRPC C# provides asynchronous -versions of each of the supported method types. For convenience, gRPC C# also -provides a synchronous method stub, but only for simple (single request/single -response) RPCs.

- -
Simple RPC
- -

Calling the simple RPC GetFeature in a synchronous way is nearly as -straightforward as calling a local method.

-
Point request = new Point { Latitude = 409146138, Longitude = -746188906 };
-Feature feature = client.GetFeature(request);
-
-

As you can see, we create and populate a request protocol buffer object (in our -case Point), and call the desired method on the client object, passing it the -request. If the RPC finishes with success, the response protocol buffer (in our -case Feature) is returned. Otherwise, an exception of type RpcException is -thrown, indicating the status code of the problem.

- -

Alternatively, if you are in an async context, you can call an asynchronous -version of the method and use the await keyword to await the result:

-
Point request = new Point { Latitude = 409146138, Longitude = -746188906 };
-Feature feature = await client.GetFeatureAsync(request);
-
-
Streaming RPCs
- -

Now let’s look at our streaming methods. If you’ve already read Creating the -server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides. The difference with respect to -simple call is that the client methods return an instance of a call object. This -provides access to request/response streams and/or the asynchronous result, -depending on the streaming type you are using.

- -

Here’s where we call the server-side streaming method ListFeatures, which has -the property ReponseStream of type IAsyncEnumerator<Feature>

-
using (var call = client.ListFeatures(request))
-{
-    while (await call.ResponseStream.MoveNext())
-    {
-        Feature feature = call.ResponseStream.Current;
-        Console.WriteLine("Received " + feature.ToString());
-    }
-}
-
-

The client-side streaming method RecordRoute is similar, except we use the -property RequestStream to write the requests one by one using WriteAsync, -and eventually signal that no more requests will be sent using CompleteAsync. -The method result can be obtained through the property ResponseAsync.

-
using (var call = client.RecordRoute())
-{
-    foreach (var point in points)
-    {
-        await call.RequestStream.WriteAsync(point);
-    }
-    await call.RequestStream.CompleteAsync();
-
-    RouteSummary summary = await call.ResponseAsync;
-}
-
-

Finally, let’s look at our bidirectional streaming RPC RouteChat. In this -case, we write the request to RequestStream and receive the responses from -ResponseStream. As you can see from the example, the streams are independent -of each other.

-
using (var call = client.RouteChat())
-{
-    var responseReaderTask = Task.Run(async () =>
-    {
-        while (await call.ResponseStream.MoveNext())
-        {
-            var note = call.ResponseStream.Current;
-            Console.WriteLine("Received " + note);
-        }
-    });
-
-    foreach (RouteNote request in requests)
-    {
-        await call.RequestStream.WriteAsync(request);
-    }
-    await call.RequestStream.CompleteAsync();
-    await responseReaderTask;
-}
-
-

Try it out!

- -

Build the client and server:

- -
Using Visual Studio (or Visual Studio For Mac)
- - - -
Using “dotnet” command line tool
- - - -

Run the server, which will listen on port 50052:

- -
> cd RouteGuideServer/bin/Debug/netcoreapp2.1
-> dotnet exec RouteGuideServer.dll
-
- -

Run the client (in a different terminal):

- -
> cd RouteGuideClient/bin/Debug/netcoreapp2.1
-> dotnet exec RouteGuideClient.dll
-
- -

You can also run the server and client directly from Visual Studio.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/dart.html b/public/docs/tutorials/basic/dart.html deleted file mode 100644 index d1c5eee..0000000 --- a/public/docs/tutorials/basic/dart.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/dart/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/dart/index.html b/public/docs/tutorials/basic/dart/index.html deleted file mode 100644 index 592be70..0000000 --- a/public/docs/tutorials/basic/dart/index.html +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Dart – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Dart

- - - -

This tutorial provides a basic Dart programmer’s introduction to -working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol buffers. Note that the -example in this tutorial uses the proto3 version of the protocol buffers -language: you can find out more in the -proto3 language -guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc-dart/example/route_guide. -To download the example, clone the grpc-dart repository by running the following -command:

-
$ git clone https://github.com/grpc/grpc-dart.git
-

Then change your current directory to grpc-dart/example/route_guide:

-
$ cd grpc-dart/example/route_guide
-

You also should have the relevant tools installed to generate the server and client interface code - if you don’t already, follow the setup instructions in the Dart quick start guide.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol buffers. You can see the -complete .proto file in -example/route_guide/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here’s the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special Dart plugin. -This is similar to what we did in the quickstart guide

- -

From the route_guide example directory run :

-
 protoc -I protos/ protos/route_guide.proto --dart_out=grpc:lib/src/generated
-

Running this command generates the following files in the lib/src/generated -directory under the route_guide example directory:

- - - -

This contains:

- - - -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job:

- - - -

You can find our example RouteGuide server in -grpc-dart/example/route_guide/lib/src/server.dart. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a RouteGuideService class that extends the -generated abstract RouteGuideServiceBase class:

-
class RouteGuideService extends RouteGuideServiceBase {
-  Future<Feature> getFeature(grpc.ServiceCall call, Point request) async {
-    ...
-  }
-
-  Stream<Feature> listFeatures(
-      grpc.ServiceCall call, Rectangle request) async* {
-    ...
-  }
-
-  Future<RouteSummary> recordRoute(
-      grpc.ServiceCall call, Stream<Point> request) async {
-    ...
-  }
-
-  Stream<RouteNote> routeChat(
-      grpc.ServiceCall call, Stream<RouteNote> request) async* {
-    ...
-  }
-
-  ...
-}
-
Simple RPC
- -

RouteGuideService implements all our service methods. Let’s look at the -simplest type first, GetFeature, which just gets a Point from the client and -returns the corresponding feature information from its database in a Feature.

-
/// GetFeature handler. Returns a feature for the given location.
-/// The [context] object provides access to client metadata, cancellation, etc.
-@override
-Future<Feature> getFeature(grpc.ServiceCall call, Point request) async {
-  return featuresDb.firstWhere((f) => f.location == request,
-      orElse: () => new Feature()..location = request);
-}
-

The method is passed a context object for the RPC and the client’s Point -protocol buffer request. It returns a Feature protocol buffer object with the -response information. In the method we populate the Feature with the appropriate -information, and then return it to the gRPC framework, which sends it back to -the client.

- -
Server-side streaming RPC
- -

Now let’s look at one of our streaming RPCs. ListFeatures is a server-side -streaming RPC, so we need to send back multiple Features to our client.

-
/// ListFeatures handler. Returns a stream of features within the given
-/// rectangle.
-@override
-Stream<Feature> listFeatures(
-    grpc.ServiceCall call, Rectangle request) async* {
-  final normalizedRectangle = _normalize(request);
-  // For each feature, check if it is in the given bounding box
-  for (var feature in featuresDb) {
-    if (feature.name.isEmpty) continue;
-    final location = feature.location;
-    if (_contains(normalizedRectangle, location)) {
-      yield feature;
-    }
-  }
-}
-

As you can see, instead of getting and returning simple request and response -objects in our method, this time we get a request object (the Rectangle in -which our client wants to find Features) and return a Stream of Feature -objects.

- -

In the method, we populate as many Feature objects as we need to return, -adding them to the returned stream using yield. The stream is automatically -closed when the method returns, telling gRPC that we have finished writing -responses.

- -

Should any error happen in this call, the error will be added as an exception -to the stream, and the gRPC layer will translate it into an appropriate RPC -status to be sent on the wire.

- -
Client-side streaming RPC
- -

Now let’s look at something a little more complicated: the client-side -streaming method RecordRoute, where we get a stream of Points from the -client and return a single RouteSummary with information about their trip. As -you can see, this time the request parameter is a stream, which the server can -use to both read request messages from the client. The server returns its single -response just like in the simple RPC case.

-
/// RecordRoute handler. Gets a stream of points, and responds with statistics
-/// about the "trip": number of points, number of known features visited,
-/// total distance traveled, and total time spent.
-@override
-Future<RouteSummary> recordRoute(
-    grpc.ServiceCall call, Stream<Point> request) async {
-  int pointCount = 0;
-  int featureCount = 0;
-  double distance = 0.0;
-  Point previous;
-  final timer = new Stopwatch();
-
-  await for (var location in request) {
-    if (!timer.isRunning) timer.start();
-    pointCount++;
-    final feature = featuresDb.firstWhere((f) => f.location == location,
-        orElse: () => null);
-    if (feature != null) {
-      featureCount++;
-    }
-    // For each point after the first, add the incremental distance from the
-    // previous point to the total distance value.
-    if (previous != null) distance += _distance(previous, location);
-    previous = location;
-  }
-  timer.stop();
-  return new RouteSummary()
-    ..pointCount = pointCount
-    ..featureCount = featureCount
-    ..distance = distance.round()
-    ..elapsedTime = timer.elapsed.inSeconds;
-}
-

In the method body we use await for in the request stream to repeatedly read -in our client’s requests (in this case Point objects) until there are no more -messages. Once the request stream is done, the server can return its -RouteSummary.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
/// RouteChat handler. Receives a stream of message/location pairs, and
-/// responds with a stream of all previous messages at each of those
-/// locations.
-@override
-Stream<RouteNote> routeChat(
-    grpc.ServiceCall call, Stream<RouteNote> request) async* {
-  await for (var note in request) {
-    final notes = routeNotes.putIfAbsent(note.location, () => <RouteNote>[]);
-    for (var note in notes) yield note;
-    notes.add(note);
-  }
-}
-

This time we get a stream of RouteNote that, as in our client-side streaming -example, can be used to read messages. However, this time we return values via -our method’s returned stream while the client is still writing messages to -their message stream.

- -

The syntax for reading and writing here is the same as our client-streaming and -server-streaming methods. Although each side will always get the other’s messages -in the order they were written, both the client and server can read and write in -any order — the streams operate completely independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
Future<Null> main(List<String> args) async {
-  final server =
-      new grpc.Server([new RouteGuideService()]);
-  await server.serve(port: 8080);
-  print('Server listening...');
-}
-

To build and start a server, we:

- -
    -
  1. Create an instance of the gRPC server using new grpc.Server(), -giving a list of service implementations.
  2. -
  3. Call serve() on the server to start listening for requests, optionally passing -in the address and port to listen on. The server will continue to serve requests -asynchronously until shutdown() is called on it.
  4. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a Dart client for our RouteGuide -service. You can see our complete example client code in -grpc-dart/example/route_guide/lib/src/client.dart.

- -

Creating a stub

- -

To call service methods, we first need to create a gRPC channel to communicate -with the server. We create this by passing the server address and port number to -new ClientChannel() as follows:

-
final channel = new ClientChannel('127.0.0.1',
-    port: 8080,
-    options: const ChannelOptions(
-        credentials: const ChannelCredentials.insecure()));
-

You can use ChannelOptions to set TLS options (e.g., trusted certificates) for -the channel, if necessary.

- -

Once the gRPC channel is setup, we need a client stub to perform RPCs. We -get by creating a new instance of the RouteGuideClient object provided in the -package we generated from our .proto.

-
final client = new RouteGuideClient(channel,
-    options: new CallOptions(timeout: new Duration(seconds: 30)));
-

You can use CallOptions to set the auth credentials (e.g., GCE credentials, -JWT credentials) if the service you request requires that - however, we don’t -need to do this for our RouteGuide service.

- -

Calling service methods

- -

Now let’s look at how we call our service methods. Note that in gRPC-Dart, RPCs -are always asynchronous, which means that the RPC returns a Future or Stream -that must be listened to, to get the response from the server or an error.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local method.

-
final point = new Point()
-  ..latitude = 409146138
-  ..longitude = -746188906;
-final feature = await stub.getFeature(point));
-

As you can see, we call the method on the stub we got earlier. In our method -parameters we pass a request protocol buffer object (in our case Point). -We can also pass an optional CallOptions object which lets us change our RPC’s -behaviour if necessary, such as time-out. If the call doesn’t return an error, -the returned Future completes with the response information from the server. -If there is an error, the Future will complete with the error.

- -
Server-side streaming RPC
- -

Here’s where we call the server-side streaming method ListFeatures, which -returns a stream of geographical Features. If you’ve already read Creating -the server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides.

-
final rect = new Rectangle()...; // initialize a Rectangle
-
-try {
-  await for (var feature in stub.listFeatures(rect)) {
-    print(feature);
-  }
-catch (e) {
-  print('ERROR: $e');
-}
-

As in the simple RPC, we pass the method a request. However, instead of getting -a Future back, we get a Stream. The client can use the stream to read the -server’s responses.

- -

We use await for on the returned stream to repeatedly read in the server’s -responses to a response protocol buffer object (in this case a Feature) until -there are no more messages.

- -
Client-side streaming RPC
- -

The client-side streaming method RecordRoute is similar to the server-side -method, except that we pass the method a Stream and get a Future back.

-
final random = new Random();
-
-// Generate a number of random points
-Stream<Point> generateRoute(int count) async* {
-  for (int i = 0; i < count; i++) {
-    final point = featuresDb[random.nextInt(featuresDb.length)].location;
-    yield point;
-  }
-}
-
-final pointCount = random.nextInt(100) + 2; // Traverse at least two points
-
-final summary = await stub.recordRoute(generateRoute(pointCount));
-print('Route summary: $summary');
-

Since the generateRoute() method is async*, the points will be generated when -gRPC listens to the request stream and sends the point messages to the server. Once -the stream is done (when generateRoute() returns), gRPC knows that we’ve finished -writing and are expecting to receive a response. The returned Future will either -complete with the RouteSummary message received from the server, or an error.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat(). As in the -case of RecordRoute, we pass the method a stream where we will write the request -messages, and like in ListFeatures, we get back a stream that we can use to read -the response messages. However, this time we will send values via our method’s stream -while the server is also writing messages to their message stream.

-
Stream<RouteNote> outgoingNotes = ...;
-
-final responses = stub.routeChat(outgoingNotes);
-await for (var note in responses) {
-  print('Got message ${note.message} at ${note.location.latitude}, ${note
-      .location.longitude}');
-}
-

The syntax for reading and writing here is very similar to our client-side and -server-side streaming methods. Although each side will always get the other’s -messages in the order they were written, both the client and server can read and -write in any order — the streams operate completely independently.

- -

Try it out!

- -

Go to the examples/route_guide folder.

- -

First, make sure dependencies are downloaded:

-
$ pub get
-

To run the server, simply:

-
$ dart bin/server.dart
-

Likewise, to run the client:

-
$ dart bin/client.dart
-

Reporting issues

- -

Should you encounter an issue, please help us out by -filing issues -in our issue tracker.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/go.html b/public/docs/tutorials/basic/go.html deleted file mode 100644 index 95d3f76..0000000 --- a/public/docs/tutorials/basic/go.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/go/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/go/index.html b/public/docs/tutorials/basic/go/index.html deleted file mode 100644 index 5d8642d..0000000 --- a/public/docs/tutorials/basic/go/index.html +++ /dev/null @@ -1,675 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Go – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Go

- - - -

This tutorial provides a basic Go programmer’s introduction to -working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol buffers. Note that the -example in this tutorial uses the proto3 version of the protocol buffers -language: you can find out more in the -proto3 language -guide and the Go -generated code -guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc-go/examples/route_guide. -To download the example, clone the grpc-go repository by running the following -command:

-
$ go get google.golang.org/grpc
-

Then change your current directory to grpc-go/examples/route_guide:

-
$ cd $GOPATH/src/google.golang.org/grpc/examples/route_guide
-

You also should have the relevant tools installed to generate the server and client interface code - if you don’t already, follow the setup instructions in the Go quick start guide.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol buffers. You can see the -complete .proto file in -examples/route_guide/routeguide/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here’s the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special gRPC Go plugin. -This is similar to what we did in the quickstart guide

- -

From the route_guide example directory run :

-
 protoc -I routeguide/ routeguide/route_guide.proto --go_out=plugins=grpc:routeguide
-

Running this command generates the following file in the routeguide directory under the route_guide example directory: -- route_guide.pb.go

- -

This contains: -- All the protocol buffer code to populate, serialize, and retrieve our request - and response message types -- An interface type (or stub) for clients to call with the methods defined in - the RouteGuide service. -- An interface type for servers to implement, also with the methods defined in - the RouteGuide service.

- -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job:

- - - -

You can find our example RouteGuide server in -grpc-go/examples/route_guide/server/server.go. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a routeGuideServer struct type that implements the generated RouteGuideServer interface:

-
type routeGuideServer struct {
-        ...
-}
-...
-
-func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
-        ...
-}
-...
-
-func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
-        ...
-}
-...
-
-func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
-        ...
-}
-...
-
-func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
-        ...
-}
-...
-
Simple RPC
- -

routeGuideServer implements all our service methods. Let’s look at the -simplest type first, GetFeature, which just gets a Point from the client and -returns the corresponding feature information from its database in a Feature.

-
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
-	for _, feature := range s.savedFeatures {
-		if proto.Equal(feature.Location, point) {
-			return feature, nil
-		}
-	}
-	// No feature was found, return an unnamed feature
-	return &pb.Feature{"", point}, nil
-}
-

The method is passed a context object for the RPC and the client’s Point -protocol buffer request. It returns a Feature protocol buffer object with the -response information and an error. In the method we populate the Feature -with the appropriate information, and then return it along with an nil error -to tell gRPC that we’ve finished dealing with the RPC and that the Feature can -be returned to the client.

- -
Server-side streaming RPC
- -

Now let’s look at one of our streaming RPCs. ListFeatures is a server-side -streaming RPC, so we need to send back multiple Features to our client.

-
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
-	for _, feature := range s.savedFeatures {
-		if inRange(feature.Location, rect) {
-			if err := stream.Send(feature); err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-

As you can see, instead of getting simple request and response objects in our -method parameters, this time we get a request object (the Rectangle in which -our client wants to find Features) and a special -RouteGuide_ListFeaturesServer object to write our responses.

- -

In the method, we populate as many Feature objects as we need to return, -writing them to the RouteGuide_ListFeaturesServer using its Send() method. -Finally, as in our simple RPC, we return a nil error to tell gRPC that we’ve -finished writing responses. Should any error happen in this call, we return a -non-nil error; the gRPC layer will translate it into an appropriate RPC status -to be sent on the wire.

- -
Client-side streaming RPC
- -

Now let’s look at something a little more complicated: the client-side -streaming method RecordRoute, where we get a stream of Points from the -client and return a single RouteSummary with information about their trip. As -you can see, this time the method doesn’t have a request parameter at all. -Instead, it gets a RouteGuide_RecordRouteServer stream, which the server can -use to both read and write messages - it can receive client messages using -its Recv() method and return its single response using its SendAndClose() -method.

-
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
-	var pointCount, featureCount, distance int32
-	var lastPoint *pb.Point
-	startTime := time.Now()
-	for {
-		point, err := stream.Recv()
-		if err == io.EOF {
-			endTime := time.Now()
-			return stream.SendAndClose(&pb.RouteSummary{
-				PointCount:   pointCount,
-				FeatureCount: featureCount,
-				Distance:     distance,
-				ElapsedTime:  int32(endTime.Sub(startTime).Seconds()),
-			})
-		}
-		if err != nil {
-			return err
-		}
-		pointCount++
-		for _, feature := range s.savedFeatures {
-			if proto.Equal(feature.Location, point) {
-				featureCount++
-			}
-		}
-		if lastPoint != nil {
-			distance += calcDistance(lastPoint, point)
-		}
-		lastPoint = point
-	}
-}
-

In the method body we use the RouteGuide_RecordRouteServer’s Recv() method to -repeatedly read in our client’s requests to a request object (in this case a -Point) until there are no more messages: the server needs to check the -error returned from Read() after each call. If this is nil, the stream is -still good and it can continue reading; if it’s io.EOF the message stream has -ended and the server can return its RouteSummary. If it has any other value, -we return the error “as is” so that it’ll be translated to an RPC status by the -gRPC layer.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
-	for {
-		in, err := stream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			return err
-		}
-		key := serialize(in.Location)
-                ... // look for notes to be sent to client
-		for _, note := range s.routeNotes[key] {
-			if err := stream.Send(note); err != nil {
-				return err
-			}
-		}
-	}
-}
-

This time we get a RouteGuide_RouteChatServer stream that, as in our -client-side streaming example, can be used to read and write messages. However, -this time we return values via our method’s stream while the client is still -writing messages to their message stream.

- -

The syntax for reading and writing here is very similar to our client-streaming -method, except the server uses the stream’s Send() method rather than -SendAndClose() because it’s writing multiple responses. Although each side -will always get the other’s messages in the order they were written, both the -client and server can read and write in any order — the streams operate -completely independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
flag.Parse()
-lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
-if err != nil {
-        log.Fatalf("failed to listen: %v", err)
-}
-grpcServer := grpc.NewServer()
-pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
-... // determine whether to use TLS
-grpcServer.Serve(lis)
-

To build and start a server, we:

- -
    -
  1. Specify the port we want to use to listen for client requests using lis, err -:= net.Listen("tcp", fmt.Sprintf(":%d", *port)).
  2. -
  3. Create an instance of the gRPC server using grpc.NewServer().
  4. -
  5. Register our service implementation with the gRPC server.
  6. -
  7. Call Serve() on the server with our port details to do a blocking wait -until the process is killed or Stop() is called.
  8. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a Go client for our RouteGuide -service. You can see our complete example client code in -grpc-go/examples/route_guide/client/client.go.

- -

Creating a stub

- -

To call service methods, we first need to create a gRPC channel to communicate -with the server. We create this by passing the server address and port number to -grpc.Dial() as follows:

-
conn, err := grpc.Dial(*serverAddr)
-if err != nil {
-    ...
-}
-defer conn.Close()
-

You can use DialOptions to set the auth credentials (e.g., TLS, GCE -credentials, JWT credentials) in grpc.Dial if the service you request requires -that - however, we don’t need to do this for our RouteGuide service.

- -

Once the gRPC channel is setup, we need a client stub to perform RPCs. We -get this using the NewRouteGuideClient method provided in the pb package we -generated from our .proto.

-
client := pb.NewRouteGuideClient(conn)
-

Calling service methods

- -

Now let’s look at how we call our service methods. Note that in gRPC-Go, RPCs -operate in a blocking/synchronous mode, which means that the RPC call waits for -the server to respond, and will either return a response or an error.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local method.

-
feature, err := client.GetFeature(context.Background(), &pb.Point{409146138, -746188906})
-if err != nil {
-        ...
-}
-

As you can see, we call the method on the stub we got earlier. In our method -parameters we create and populate a request protocol buffer object (in our case -Point). We also pass a context.Context object which lets us change our RPC’s -behaviour if necessary, such as time-out/cancel an RPC in flight. If the call -doesn’t return an error, then we can read the response information from the -server from the first return value.

-
log.Println(feature)
-
Server-side streaming RPC
- -

Here’s where we call the server-side streaming method ListFeatures, which -returns a stream of geographical Features. If you’ve already read Creating -the server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides.

-
rect := &pb.Rectangle{ ... }  // initialize a pb.Rectangle
-stream, err := client.ListFeatures(context.Background(), rect)
-if err != nil {
-    ...
-}
-for {
-    feature, err := stream.Recv()
-    if err == io.EOF {
-        break
-    }
-    if err != nil {
-        log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
-    }
-    log.Println(feature)
-}
-

As in the simple RPC, we pass the method a context and a request. However, -instead of getting a response object back, we get back an instance of -RouteGuide_ListFeaturesClient. The client can use the -RouteGuide_ListFeaturesClient stream to read the server’s responses.

- -

We use the RouteGuide_ListFeaturesClient’s Recv() method to repeatedly read -in the server’s responses to a response protocol buffer object (in this case a -Feature) until there are no more messages: the client needs to check the error -err returned from Recv() after each call. If nil, the stream is still good -and it can continue reading; if it’s io.EOF then the message stream has ended; -otherwise there must be an RPC error, which is passed over through err.

- -
Client-side streaming RPC
- -

The client-side streaming method RecordRoute is similar to the server-side -method, except that we only pass the method a context and get a -RouteGuide_RecordRouteClient stream back, which we can use to both write and -read messages.

-
// Create a random number of random points
-r := rand.New(rand.NewSource(time.Now().UnixNano()))
-pointCount := int(r.Int31n(100)) + 2 // Traverse at least two points
-var points []*pb.Point
-for i := 0; i < pointCount; i++ {
-	points = append(points, randomPoint(r))
-}
-log.Printf("Traversing %d points.", len(points))
-stream, err := client.RecordRoute(context.Background())
-if err != nil {
-	log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)
-}
-for _, point := range points {
-	if err := stream.Send(point); err != nil {
-		if err == io.EOF {
-			break
-		}
-		log.Fatalf("%v.Send(%v) = %v", stream, point, err)
-	}
-}
-reply, err := stream.CloseAndRecv()
-if err != nil {
-	log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)
-}
-log.Printf("Route summary: %v", reply)
-

The RouteGuide_RecordRouteClient has a Send() method that we can use to send -requests to the server. Once we’ve finished writing our client’s requests to the -stream using Send(), we need to call CloseAndRecv() on the stream to let -gRPC know that we’ve finished writing and are expecting to receive a response. -We get our RPC status from the err returned from CloseAndRecv(). If the -status is nil, then the first return value from CloseAndRecv() will be a -valid server response.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat(). As in the -case of RecordRoute, we only pass the method a context object and get back a -stream that we can use to both write and read messages. However, this time we -return values via our method’s stream while the server is still writing messages -to their message stream.

-
stream, err := client.RouteChat(context.Background())
-waitc := make(chan struct{})
-go func() {
-	for {
-		in, err := stream.Recv()
-		if err == io.EOF {
-			// read done.
-			close(waitc)
-			return
-		}
-		if err != nil {
-			log.Fatalf("Failed to receive a note : %v", err)
-		}
-		log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
-	}
-}()
-for _, note := range notes {
-	if err := stream.Send(note); err != nil {
-		log.Fatalf("Failed to send a note: %v", err)
-	}
-}
-stream.CloseSend()
-<-waitc
-

The syntax for reading and writing here is very similar to our client-side -streaming method, except we use the stream’s CloseSend() method once we’ve -finished our call. Although each side will always get the other’s messages in -the order they were written, both the client and server can read and write in -any order — the streams operate completely independently.

- -

Try it out!

- -

To compile and run the server, assuming you are in the folder -$GOPATH/src/google.golang.org/grpc/examples/route_guide, simply:

-
$ go run server/server.go
-

Likewise, to run the client:

-
$ go run client/client.go
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/java.html b/public/docs/tutorials/basic/java.html deleted file mode 100644 index f5ac400..0000000 --- a/public/docs/tutorials/basic/java.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/java/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/java/index.html b/public/docs/tutorials/basic/java/index.html deleted file mode 100644 index affcfe5..0000000 --- a/public/docs/tutorials/basic/java/index.html +++ /dev/null @@ -1,799 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Java – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Java

- - - -

This tutorial provides a basic Java programmer’s introduction to -working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol -buffers. Note -that the example in this tutorial uses the -proto3 version of the protocol -buffers language: you can find out more in the proto3 language -guide and Java -generated code -guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc-java/examples/src/main/java/io/grpc/examples. -To download the example, clone the latest release in grpc-java repository by -running the following command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc-java.git
-

Then change your current directory to grpc-java/examples:

-
$ cd grpc-java/examples
-

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol -buffers. You can -see the complete .proto file in -grpc-java/examples/src/main/proto/route_guide.proto.

- -

As we’re generating Java code in this example, we’ve specified a java_package -file option in our .proto:

-
option java_package = "io.grpc.examples.routeguide";
-

This specifies the package we want to use for our generated Java classes. If no -explicit java_package option is given in the .proto file, then by default the -proto package (specified using the “package” keyword) will be used. However, -proto packages generally do not make good Java packages since proto packages are -not expected to start with reverse domain names. If we generate code in another -language from this .proto, the java_package option has no effect.

- -

To define a service, we specify a named service in the .proto file:

-
service RouteGuide {
-   ...
-}
-

Then we define rpc methods inside our service definition, specifying their -request and response types. gRPC lets you define four kinds of service methods, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special gRPC Java plugin. You need to use the -proto3 compiler (which supports -both proto2 and proto3 syntax) in order to generate gRPC services.

- -

When using Gradle or Maven, the protoc build plugin can generate the necessary -code as part of the build. You can refer to the README for -how to generate code from your own .proto files.

- -

The following classes are generated from our service definition:

- - - -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job:

- - - -

You can find our example RouteGuide server in -grpc-java/examples/src/main/java/io/grpc/examples/routeguide/RouteGuideServer.java. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a RouteGuideService class that extends the -generated RouteGuideGrpc.RouteGuideImplBase abstract class:

-
private static class RouteGuideService extends RouteGuideGrpc.RouteGuideImplBase {
-...
-}
-

Simple RPC

- -

RouteGuideService implements all our service methods. Let’s -look at the simplest type first, GetFeature, which just gets a Point from -the client and returns the corresponding feature information from its database -in a Feature.

-
@Override
-public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
-  responseObserver.onNext(checkFeature(request));
-  responseObserver.onCompleted();
-}
-
-...
-
-private Feature checkFeature(Point location) {
-  for (Feature feature : features) {
-    if (feature.getLocation().getLatitude() == location.getLatitude()
-        && feature.getLocation().getLongitude() == location.getLongitude()) {
-      return feature;
-    }
-  }
-
-  // No feature was found, return an unnamed feature.
-  return Feature.newBuilder().setName("").setLocation(location).build();
-}
-

getFeature() takes two parameters:

- - - -

To return our response to the client and complete the call:

- -
    -
  1. We construct and populate a Feature response object to return to the -client, as specified in our service definition. In this example, we do this -in a separate private checkFeature() method.
  2. -
  3. We use the response observer’s onNext() method to return the Feature.
  4. -
  5. We use the response observer’s onCompleted() method to specify that we’ve -finished dealing with the RPC.
  6. -
- -
Server-side streaming RPC
- -

Next let’s look at one of our streaming RPCs. ListFeatures is a server-side -streaming RPC, so we need to send back multiple Features to our client.

-
private final Collection<Feature> features;
-
-...
-
-@Override
-public void listFeatures(Rectangle request, StreamObserver<Feature> responseObserver) {
-  int left = min(request.getLo().getLongitude(), request.getHi().getLongitude());
-  int right = max(request.getLo().getLongitude(), request.getHi().getLongitude());
-  int top = max(request.getLo().getLatitude(), request.getHi().getLatitude());
-  int bottom = min(request.getLo().getLatitude(), request.getHi().getLatitude());
-
-  for (Feature feature : features) {
-    if (!RouteGuideUtil.exists(feature)) {
-      continue;
-    }
-
-    int lat = feature.getLocation().getLatitude();
-    int lon = feature.getLocation().getLongitude();
-    if (lon >= left && lon <= right && lat >= bottom && lat <= top) {
-      responseObserver.onNext(feature);
-    }
-  }
-  responseObserver.onCompleted();
-}
-

Like the simple RPC, this method gets a request object (the Rectangle in which -our client wants to find Features) and a StreamObserver response observer.

- -

This time, we get as many Feature objects as we need to return to the client -(in this case, we select them from the service’s feature collection based on -whether they’re inside our request Rectangle), and write them each in turn to -the response observer using its onNext() method. Finally, as in our simple -RPC, we use the response observer’s onCompleted() method to tell gRPC that -we’ve finished writing responses.

- -
Client-side streaming RPC
- -

Now let’s look at something a little more complicated: the client-side streaming -method RecordRoute, where we get a stream of Points from the client and -return a single RouteSummary with information about their trip.

-
@Override
-public StreamObserver<Point> recordRoute(final StreamObserver<RouteSummary> responseObserver) {
-  return new StreamObserver<Point>() {
-    int pointCount;
-    int featureCount;
-    int distance;
-    Point previous;
-    long startTime = System.nanoTime();
-
-    @Override
-    public void onNext(Point point) {
-      pointCount++;
-      if (RouteGuideUtil.exists(checkFeature(point))) {
-        featureCount++;
-      }
-      // For each point after the first, add the incremental distance from the previous point
-      // to the total distance value.
-      if (previous != null) {
-        distance += calcDistance(previous, point);
-      }
-      previous = point;
-    }
-
-    @Override
-    public void onError(Throwable t) {
-      logger.log(Level.WARNING, "Encountered error in recordRoute", t);
-    }
-
-    @Override
-    public void onCompleted() {
-      long seconds = NANOSECONDS.toSeconds(System.nanoTime() - startTime);
-      responseObserver.onNext(RouteSummary.newBuilder().setPointCount(pointCount)
-          .setFeatureCount(featureCount).setDistance(distance)
-          .setElapsedTime((int) seconds).build());
-      responseObserver.onCompleted();
-    }
-  };
-}
-

As you can see, like the previous method types our method gets a -StreamObserver response observer parameter, but this time it returns a -StreamObserver for the client to write its Points.

- -

In the method body we instantiate an anonymous StreamObserver to return, in -which we:

- - - -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
@Override
-public StreamObserver<RouteNote> routeChat(final StreamObserver<RouteNote> responseObserver) {
-  return new StreamObserver<RouteNote>() {
-    @Override
-    public void onNext(RouteNote note) {
-      List<RouteNote> notes = getOrCreateNotes(note.getLocation());
-
-      // Respond with all previous notes at this location.
-      for (RouteNote prevNote : notes.toArray(new RouteNote[0])) {
-        responseObserver.onNext(prevNote);
-      }
-
-      // Now add the new note to the list
-      notes.add(note);
-    }
-
-    @Override
-    public void onError(Throwable t) {
-      logger.log(Level.WARNING, "Encountered error in routeChat", t);
-    }
-
-    @Override
-    public void onCompleted() {
-      responseObserver.onCompleted();
-    }
-  };
-}
-

As with our client-side streaming example, we both get and return a -StreamObserver response observer, except this time we return values via our -method’s response observer while the client is still writing messages to their -message stream. The syntax for reading and writing here is exactly the same as -for our client-streaming and server-streaming methods. Although each side will -always get the other’s messages in the order they were written, both the client -and server can read and write in any order — the streams operate completely -independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
public RouteGuideServer(int port, URL featureFile) throws IOException {
-  this(ServerBuilder.forPort(port), port, RouteGuideUtil.parseFeatures(featureFile));
-}
-
-/** Create a RouteGuide server using serverBuilder as a base and features as data. */
-public RouteGuideServer(ServerBuilder<?> serverBuilder, int port, Collection<Feature> features) {
-  this.port = port;
-  server = serverBuilder.addService(new RouteGuideService(features))
-      .build();
-}
-...
-public void start() throws IOException {
-  server.start();
-  logger.info("Server started, listening on " + port);
- ...
-}
-

As you can see, we build and start our server using a ServerBuilder.

- -

To do this, we:

- -
    -
  1. Specify the address and port we want to use to listen for client requests -using the builder’s forPort() method.
  2. -
  3. Create an instance of our service implementation class RouteGuideService -and pass it to the builder’s addService() method.
  4. -
  5. Call build() and start() on the builder to create and start an RPC server -for our service.
  6. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a Java client for our RouteGuide -service. You can see our complete example client code in -grpc-java/examples/src/main/java/io/grpc/examples/routeguide/RouteGuideClient.java.

- -

Creating a stub

- -

To call service methods, we first need to create a stub, or rather, two stubs:

- - - -

First we need to create a gRPC channel for our stub, specifying the server -address and port we want to connect to:

-
public RouteGuideClient(String host, int port) {
-  this(ManagedChannelBuilder.forAddress(host, port).usePlaintext());
-}
-
-/** Construct client for accessing RouteGuide server using the existing channel. */
-public RouteGuideClient(ManagedChannelBuilder<?> channelBuilder) {
-  channel = channelBuilder.build();
-  blockingStub = RouteGuideGrpc.newBlockingStub(channel);
-  asyncStub = RouteGuideGrpc.newStub(channel);
-}
-

We use a ManagedChannelBuilder to create the channel.

- -

Now we can use the channel to create our stubs using the newStub and -newBlockingStub methods provided in the RouteGuideGrpc class we generated -from our .proto.

-
blockingStub = RouteGuideGrpc.newBlockingStub(channel);
-asyncStub = RouteGuideGrpc.newStub(channel);
-

Calling service methods

- -

Now let’s look at how we call our service methods.

- -
Simple RPC
- -

Calling the simple RPC GetFeature on the blocking stub is as straightforward -as calling a local method.

-
Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
-Feature feature;
-try {
-  feature = blockingStub.getFeature(request);
-} catch (StatusRuntimeException e) {
-  logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
-  return;
-}
-

We create and populate a request protocol buffer object (in our case Point), -pass it to the getFeature() method on our blocking stub, and get back a -Feature.

- -

If an error occurs, it is encoded as a Status, which we can obtain from the -StatusRuntimeException.

- -
Server-side streaming RPC
- -

Next, let’s look at a server-side streaming call to ListFeatures, which -returns a stream of geographical Features:

-
Rectangle request =
-    Rectangle.newBuilder()
-        .setLo(Point.newBuilder().setLatitude(lowLat).setLongitude(lowLon).build())
-        .setHi(Point.newBuilder().setLatitude(hiLat).setLongitude(hiLon).build()).build();
-Iterator<Feature> features;
-try {
-  features = blockingStub.listFeatures(request);
-} catch (StatusRuntimeException ex) {
-  logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
-  return;
-}
-

As you can see, it’s very similar to the simple RPC we just looked at, except -instead of returning a single Feature, the method returns an Iterator that -the client can use to read all the returned Features.

- -
Client-side streaming RPC
- -

Now for something a little more complicated: the client-side streaming method -RecordRoute, where we send a stream of Points to the server and get back a -single RouteSummary. For this method we need to use the asynchronous stub. If -you’ve already read Creating the server some of this may look very -familiar - asynchronous streaming RPCs are implemented in a similar way on both -sides.

-
public void recordRoute(List<Feature> features, int numPoints) throws InterruptedException {
-  info("*** RecordRoute");
-  final CountDownLatch finishLatch = new CountDownLatch(1);
-  StreamObserver<RouteSummary> responseObserver = new StreamObserver<RouteSummary>() {
-    @Override
-    public void onNext(RouteSummary summary) {
-      info("Finished trip with {0} points. Passed {1} features. "
-          + "Travelled {2} meters. It took {3} seconds.", summary.getPointCount(),
-          summary.getFeatureCount(), summary.getDistance(), summary.getElapsedTime());
-    }
-
-    @Override
-    public void onError(Throwable t) {
-      Status status = Status.fromThrowable(t);
-      logger.log(Level.WARNING, "RecordRoute Failed: {0}", status);
-      finishLatch.countDown();
-    }
-
-    @Override
-    public void onCompleted() {
-      info("Finished RecordRoute");
-      finishLatch.countDown();
-    }
-  };
-
-  StreamObserver<Point> requestObserver = asyncStub.recordRoute(responseObserver);
-  try {
-    // Send numPoints points randomly selected from the features list.
-    Random rand = new Random();
-    for (int i = 0; i < numPoints; ++i) {
-      int index = rand.nextInt(features.size());
-      Point point = features.get(index).getLocation();
-      info("Visiting point {0}, {1}", RouteGuideUtil.getLatitude(point),
-          RouteGuideUtil.getLongitude(point));
-      requestObserver.onNext(point);
-      // Sleep for a bit before sending the next one.
-      Thread.sleep(rand.nextInt(1000) + 500);
-      if (finishLatch.getCount() == 0) {
-        // RPC completed or errored before we finished sending.
-        // Sending further requests won't error, but they will just be thrown away.
-        return;
-      }
-    }
-  } catch (RuntimeException e) {
-    // Cancel RPC
-    requestObserver.onError(e);
-    throw e;
-  }
-  // Mark the end of requests
-  requestObserver.onCompleted();
-
-  // Receiving happens asynchronously
-  finishLatch.await(1, TimeUnit.MINUTES);
-}
-

As you can see, to call this method we need to create a StreamObserver, which -implements a special interface for the server to call with its RouteSummary -response. In our StreamObserver we:

- - - -

We then pass the StreamObserver to the asynchronous stub’s recordRoute() -method and get back our own StreamObserver request observer to write our -Points to send to the server. Once we’ve finished writing points, we use the -request observer’s onCompleted() method to tell gRPC that we’ve finished -writing on the client side. Once we’re done, we check our CountDownLatch to -check that the server has completed on its side.

- -
Bidirectional streaming RPC
- -

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
public void routeChat() throws Exception {
-  info("*** RoutChat");
-  final CountDownLatch finishLatch = new CountDownLatch(1);
-  StreamObserver<RouteNote> requestObserver =
-      asyncStub.routeChat(new StreamObserver<RouteNote>() {
-        @Override
-        public void onNext(RouteNote note) {
-          info("Got message \"{0}\" at {1}, {2}", note.getMessage(), note.getLocation()
-              .getLatitude(), note.getLocation().getLongitude());
-        }
-
-        @Override
-        public void onError(Throwable t) {
-          Status status = Status.fromThrowable(t);
-          logger.log(Level.WARNING, "RouteChat Failed: {0}", status);
-          finishLatch.countDown();
-        }
-
-        @Override
-        public void onCompleted() {
-          info("Finished RouteChat");
-          finishLatch.countDown();
-        }
-      });
-
-  try {
-    RouteNote[] requests =
-        {newNote("First message", 0, 0), newNote("Second message", 0, 1),
-            newNote("Third message", 1, 0), newNote("Fourth message", 1, 1)};
-
-    for (RouteNote request : requests) {
-      info("Sending message \"{0}\" at {1}, {2}", request.getMessage(), request.getLocation()
-          .getLatitude(), request.getLocation().getLongitude());
-      requestObserver.onNext(request);
-    }
-  } catch (RuntimeException e) {
-    // Cancel RPC
-    requestObserver.onError(e);
-    throw e;
-  }
-  // Mark the end of requests
-  requestObserver.onCompleted();
-
-  // Receiving happens asynchronously
-  finishLatch.await(1, TimeUnit.MINUTES);
-}
-

As with our client-side streaming example, we both get and return a -StreamObserver response observer, except this time we send values via our -method’s response observer while the server is still writing messages to their -message stream. The syntax for reading and writing here is exactly the same as -for our client-streaming method. Although each side will always get the other’s -messages in the order they were written, both the client and server can read and -write in any order — the streams operate completely independently.

- -

Try it out!

- -

Follow the instructions in the example directory -README to -build and run the client and server.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/node.html b/public/docs/tutorials/basic/node.html deleted file mode 100644 index 9c6b727..0000000 --- a/public/docs/tutorials/basic/node.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/node/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/node/index.html b/public/docs/tutorials/basic/node/index.html deleted file mode 100644 index 4ab067b..0000000 --- a/public/docs/tutorials/basic/node/index.html +++ /dev/null @@ -1,631 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Node.js – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Node.js

- - - -

This tutorial provides a basic Node.js programmer’s introduction -to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol -buffers. Note -that the example in this tutorial uses the -proto3 version of the protocol -buffers language. You can find out more in the -proto3 language guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/node/dynamic_codegen/route_guide. -As you’ll see if you look at the repository, there’s also a very similar-looking -example in -grpc/grpc/examples/node/static_codegen/route_guide. -We have two versions of our route guide example because there are two ways to -generate the code needed to work with protocol buffers in Node.js - one approach -uses Protobuf.js to dynamically generate the code at runtime, the other uses -code statically generated using the protocol buffer compiler protoc. The -examples behave identically, and either server can be used with either client. -As suggested by the directory name, we’ll be using the version with dynamically -generated code in this document, but feel free to look at the static code -example too.

- -

To download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ cd grpc
-

Then change your current directory to examples/node:

-
$ cd examples/node
-

You also should have the relevant tools installed to generate the server and -client interface code - if you don’t already, follow the setup instructions in -the Node.js quick start guide.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol -buffers. You can -see the complete .proto file in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Loading service descriptors from proto files

- -

The Node.js library dynamically generates service descriptors and client stub -definitions from .proto files loaded at runtime.

- -

To load a .proto file, simply require the gRPC proto loader library and use its -loadSync() method, then pass the output to the gRPC library’s loadPackageDefinition method:

-
var PROTO_PATH = __dirname + '/../../../protos/route_guide.proto';
-var grpc = require('grpc');
-var protoLoader = require('@grpc/proto-loader');
-// Suggested options for similarity to existing grpc.load behavior
-var packageDefinition = protoLoader.loadSync(
-    PROTO_PATH,
-    {keepCase: true,
-     longs: String,
-     enums: String,
-     defaults: true,
-     oneofs: true
-    });
-var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
-// The protoDescriptor object has the full package hierarchy
-var routeguide = protoDescriptor.routeguide;
-
-

Once you’ve done this, the stub constructor is in the routeguide namespace -(protoDescriptor.routeguide.RouteGuide) and the service descriptor (which is -used to create a server) is a property of the stub -(protoDescriptor.routeguide.RouteGuide.service);

- -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job: -- Implementing the service interface generated from our service definition: - doing the actual “work” of our service. -- Running a gRPC server to listen for requests from clients and return the - service responses.

- -

You can find our example RouteGuide server in -examples/node/dynamic_codegen/route_guide/route_guide_server.js. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a Server constructor generated from the -RouteGuide.service descriptor object

-
var Server = new grpc.Server();
-
-

In this case we’re implementing the asynchronous version of RouteGuide, -which provides our default gRPC server behaviour.

- -

The functions in route_guide_server.js implement all our service methods. -Let’s look at the simplest type first, getFeature, which just gets a Point -from the client and returns the corresponding feature information from its -database in a Feature.

-
function checkFeature(point) {
-  var feature;
-  // Check if there is already a feature object for the given point
-  for (var i = 0; i < feature_list.length; i++) {
-    feature = feature_list[i];
-    if (feature.location.latitude === point.latitude &&
-        feature.location.longitude === point.longitude) {
-      return feature;
-    }
-  }
-  var name = '';
-  feature = {
-    name: name,
-    location: point
-  };
-  return feature;
-}
-function getFeature(call, callback) {
-  callback(null, checkFeature(call.request));
-}
-
-

The method is passed a call object for the RPC, which has the Point parameter -as a property, and a callback to which we can pass our returned Feature. In -the method body we populate a Feature corresponding to the given point and -pass it to the callback, with a null first parameter to indicate that there is -no error.

- -

Now let’s look at something a bit more complicated - a streaming RPC. -listFeatures is a server-side streaming RPC, so we need to send back multiple -Features to our client.

-
function listFeatures(call) {
-  var lo = call.request.lo;
-  var hi = call.request.hi;
-  var left = _.min([lo.longitude, hi.longitude]);
-  var right = _.max([lo.longitude, hi.longitude]);
-  var top = _.max([lo.latitude, hi.latitude]);
-  var bottom = _.min([lo.latitude, hi.latitude]);
-  // For each feature, check if it is in the given bounding box
-  _.each(feature_list, function(feature) {
-    if (feature.name === '') {
-      return;
-    }
-    if (feature.location.longitude >= left &&
-        feature.location.longitude <= right &&
-        feature.location.latitude >= bottom &&
-        feature.location.latitude <= top) {
-      call.write(feature);
-    }
-  });
-  call.end();
-}
-
-

As you can see, instead of getting the call object and callback in our method -parameters, this time we get a call object that implements the Writable -interface. In the method, we create as many Feature objects as we need to -return, writing them to the call using its write() method. Finally, we call -call.end() to indicate that we have sent all messages.

- -

If you look at the client-side streaming method RecordRoute you’ll see it’s -quite similar to the unary call, except this time the call parameter -implements the Reader interface. The call’s 'data' event fires every time -there is new data, and the 'end' event fires when all data has been read. Like -the unary case, we respond by calling the callback

-
call.on('data', function(point) {
-  // Process user data
-});
-call.on('end', function() {
-  callback(null, result);
-});
-
-

Finally, let’s look at our bidirectional streaming RPC RouteChat().

-
function routeChat(call) {
-  call.on('data', function(note) {
-    var key = pointKey(note.location);
-    /* For each note sent, respond with all previous notes that correspond to
-     * the same point */
-    if (route_notes.hasOwnProperty(key)) {
-      _.each(route_notes[key], function(note) {
-        call.write(note);
-      });
-    } else {
-      route_notes[key] = [];
-    }
-    // Then add the new note to the list
-    route_notes[key].push(JSON.parse(JSON.stringify(note)));
-  });
-  call.on('end', function() {
-    call.end();
-  });
-}
-
-

This time we get a call implementing Duplex that can be used to read and -write messages. The syntax for reading and writing here is exactly the same as -for our client-streaming and server-streaming methods. Although each side will -always get the other’s messages in the order they were written, both the client -and server can read and write in any order — the streams operate completely -independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
function getServer() {
-  var server = new grpc.Server();
-  server.addProtoService(routeguide.RouteGuide.service, {
-    getFeature: getFeature,
-    listFeatures: listFeatures,
-    recordRoute: recordRoute,
-    routeChat: routeChat
-  });
-  return server;
-}
-var routeServer = getServer();
-routeServer.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
-routeServer.start();
-
-

As you can see, we build and start our server with the following steps:

- -
    -
  1. Create a Server constructor from the RouteGuide service descriptor.
  2. -
  3. Implement the service methods.
  4. -
  5. Create an instance of the server by calling the Server constructor with -the method implementations.
  6. -
  7. Specify the address and port we want to use to listen for client requests -using the instance’s bind() method.
  8. -
  9. Call start() on the instance to start the RPC server.
  10. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a Node.js client for our RouteGuide -service. You can see our complete example client code in -examples/node/dynamic_codegen/route_guide/route_guide_client.js.

- -

Creating a stub

- -

To call service methods, we first need to create a stub. To do this, we just -need to call the RouteGuide stub constructor, specifying the server address and -port.

-
new routeguide.RouteGuide('localhost:50051', grpc.credentials.createInsecure());
-
-

Calling service methods

- -

Now let’s look at how we call our service methods. Note that all of these -methods are asynchronous: they use either events or callbacks to retrieve -results.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local asynchronous method.

-
var point = {latitude: 409146138, longitude: -746188906};
-stub.getFeature(point, function(err, feature) {
-  if (err) {
-    // process error
-  } else {
-    // process feature
-  }
-});
-
-

As you can see, we create and populate a request object. Finally, we call the -method on the stub, passing it the request and callback. If there is no error, -then we can read the response information from the server from our response -object.

-
console.log('Found feature called "' + feature.name + '" at ' +
-    feature.location.latitude/COORD_FACTOR + ', ' +
-    feature.location.longitude/COORD_FACTOR);
-
-
Streaming RPCs
- -

Now let’s look at our streaming methods. If you’ve already read Creating the -server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides. Here’s where we call the server-side -streaming method ListFeatures, which returns a stream of geographical -Features:

-
var call = client.listFeatures(rectangle);
-  call.on('data', function(feature) {
-      console.log('Found feature called "' + feature.name + '" at ' +
-          feature.location.latitude/COORD_FACTOR + ', ' +
-          feature.location.longitude/COORD_FACTOR);
-  });
-  call.on('end', function() {
-    // The server has finished sending
-  });
-  call.on('error', function(e) {
-    // An error has occurred and the stream has been closed.
-  });
-  call.on('status', function(status) {
-    // process status
-  });
-
-

Instead of passing the method a request and callback, we pass it a request and -get a Readable stream object back. The client can use the Readable’s -'data' event to read the server’s responses. This event fires with each -Feature message object until there are no more messages. Errors in the 'data' -callback will not cause the stream to be closed. The 'error' event -indicates that an error has occurred and the stream has been closed. The -'end' event indicates that the server has finished sending and no errors -occured. Only one of 'error' or 'end' will be emitted. Finally, the -'status' event fires when the server sends the status.

- -

The client-side streaming method RecordRoute is similar, except there we pass -the method a callback and get back a Writable.

-
var call = client.recordRoute(function(error, stats) {
-  if (error) {
-    callback(error);
-  }
-  console.log('Finished trip with', stats.point_count, 'points');
-  console.log('Passed', stats.feature_count, 'features');
-  console.log('Travelled', stats.distance, 'meters');
-  console.log('It took', stats.elapsed_time, 'seconds');
-});
-function pointSender(lat, lng) {
-  return function(callback) {
-    console.log('Visiting point ' + lat/COORD_FACTOR + ', ' +
-        lng/COORD_FACTOR);
-    call.write({
-      latitude: lat,
-      longitude: lng
-    });
-    _.delay(callback, _.random(500, 1500));
-  };
-}
-var point_senders = [];
-for (var i = 0; i < num_points; i++) {
-  var rand_point = feature_list[_.random(0, feature_list.length - 1)];
-  point_senders[i] = pointSender(rand_point.location.latitude,
-                                 rand_point.location.longitude);
-}
-async.series(point_senders, function() {
-  call.end();
-});
-
-

Once we’ve finished writing our client’s requests to the stream using write(), -we need to call end() on the stream to let gRPC know that we’ve finished -writing. If the status is OK, the stats object will be populated with the -server’s response.

- -

Finally, let’s look at our bidirectional streaming RPC routeChat(). In this -case, we just pass a context to the method and get back a Duplex stream -object, which we can use to both write and read messages.

-
var call = client.routeChat();
-
-

The syntax for reading and writing here is exactly the same as for our -client-streaming and server-streaming methods. Although each side will always -get the other’s messages in the order they were written, both the client and -server can read and write in any order — the streams operate completely -independently.

- -

Try it out!

- -

Build client and server:

-
$ npm install
-

Run the server, which will listen on port 50051:

-
$ node ./dynamic_codegen/route_guide/route_guide_server.js --db_path=./dynamic_codegen/route_guide/route_guide_db.json
-

Run the client (in a different terminal):

-
$ node ./dynamic_codegen/route_guide/route_guide_client.js --db_path=./dynamic_codegen/route_guide/route_guide_db.json
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/objective-c.html b/public/docs/tutorials/basic/objective-c.html deleted file mode 100644 index 57523ae..0000000 --- a/public/docs/tutorials/basic/objective-c.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/objective-c/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/objective-c/index.html b/public/docs/tutorials/basic/objective-c/index.html deleted file mode 100644 index 2b62cac..0000000 --- a/public/docs/tutorials/basic/objective-c/index.html +++ /dev/null @@ -1,506 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Objective-C – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Objective-C

- - - -

This tutorial provides a basic Objective-C programmer’s -introduction to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes a passing familiarity with protocol -buffers. Note -that the example in this tutorial uses the proto3 version of the protocol -buffers language: you can find out more in -the proto3 language -guide and the -Objective-C generated code -guide.

- -
- -

- -

Why use gRPC?

- -

With gRPC you can define your service once in a .proto file and implement -clients and servers in any of gRPC’s supported languages, which in turn can be -run in environments ranging from servers inside Google to your own tablet - all -the complexity of communication between different languages and environments is -handled for you by gRPC. You also get all the advantages of working with -protocol buffers, including efficient serialization, a simple IDL, and easy -interface updating.

- -

gRPC and proto3 are specially suited for mobile clients: gRPC is implemented on -top of HTTP/2, which results in network bandwidth savings over using HTTP/1.1. -Serialization and parsing of the proto binary format is more efficient than the -equivalent JSON, resulting in CPU and battery savings. And proto3 uses a runtime -that has been optimized over the years at Google to keep code size to a minimum. -The latter is important in Objective-C, because the ability of the compiler to -strip unused code is limited by the dynamic nature of the language.

- -

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/objective-c/route_guide. -To download the example, clone the grpc repository by running the following -commands:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ cd grpc
-$ git submodule update --init
-

Then change your current directory to examples/objective-c/route_guide:

-
$ cd examples/objective-c/route_guide
-

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

You also should have Cocoapods installed, as -well as the relevant tools to generate the client library code (and a server in -another language, for testing). You can obtain the latter by following these -setup instructions.

- -

- -

Try it out!

- -

To try the sample app, we need a gRPC server running locally. Let’s compile and -run, for example, the C++ server in this repository:

-
$ pushd ../../cpp/route_guide
-$ make
-$ ./route_guide_server &
-$ popd
-

Now have Cocoapods generate and install the client library for our .proto files:

-
$ pod install
-

(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods -doesn’t have it yet on your computer’s cache).

- -

Finally, open the XCode workspace created by Cocoapods, and run the app. You can -check the calling code in ViewControllers.m and see the results in XCode’s log -console.

- -

The next sections guide you step-by-step through how this proto service is -defined, how to generate a client library from it, and how to create an app that -uses that library.

- -

- -

Defining the service

- -

First let’s look at how the service we’re using is defined. A gRPC service and -its method request and response types using protocol -buffers. You can -see the complete .proto file for our example in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. Protocol buffers let you define four kinds of -service method, all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

You can specify a prefix to be used for your generated classes by adding the -objc_class_prefix option at the top of the file. For example:

-
option objc_class_prefix = "RTG";
-

- -

Generating client code

- -

Next we need to generate the gRPC client interfaces from our .proto service -definition. We do this using the protocol buffer compiler (protoc) with a -special gRPC Objective-C plugin.

- -

For simplicity, we’ve provided a Podspec -file -that runs protoc for you with the appropriate plugin, input, and output, and -describes how to compile the generated files. You just need to run in this -directory (examples/objective-c/route_guide):

-
$ pod install
-

which, before installing the generated library in the XCode project of this sample, runs:

-
$ protoc -I ../../protos --objc_out=Pods/RouteGuide --objcgrpc_out=Pods/RouteGuide ../../protos/route_guide.proto
-

Running this command generates the following files under Pods/RouteGuide/:

- - - -

These contain:

- - - -

You can also use the provided Podspec file to generate client code from any -other proto service definition; just replace the name (matching the file name), -version, and other metadata.

- -

- -

Creating the client application

- -

In this section, we’ll look at creating an Objective-C client for our -RouteGuide service. You can see our complete example client code in -examples/objective-c/route_guide/ViewControllers.m. -(Note: In your apps, for maintainability and readability reasons, you shouldn’t -put all of your view controllers in a single file; it’s done here only to -simplify the learning process).

- -

Constructing a service object

- -

To call service methods, we first need to create a service object, an instance -of the generated RTGRouteGuide class. The designated initializer of the class -expects a NSString * with the server address and port we want to connect to:

-
#import <GRPCClient/GRPCCall+Tests.h>
-#import <RouteGuide/RouteGuide.pbrpc.h>
-
-static NSString * const kHostAddress = @"localhost:50051";
-...
-[GRPCCall useInsecureConnectionsForHost:kHostAddress];
-
-RTGRouteGuide *service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
-

Notice that before constructing our service object we’ve told the gRPC library -to use insecure connections for that host:port pair. This is because the server -we will be using to test our client doesn’t use -TLS. This is fine -because it will be running locally on our development machine. The most common -case, though, is connecting with a gRPC server on the internet, running gRPC -over TLS. For that case, the useInsecureConnectionsForHost: call isn’t needed, -and the port defaults to 443 if absent.

- -

Calling service methods

- -

Now let’s look at how we call our service methods. As you will see, all these -methods are asynchronous, so you can call them from the main thread of your app -without worrying about freezing your UI or the OS killing your app.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is as straightforward as calling any other -asynchronous method on Cocoa.

-
RTGPoint *point = [RTGPoint message];
-point.latitude = 40E7;
-point.longitude = -74E7;
-
-[service getFeatureWithRequest:point handler:^(RTGFeature *response, NSError *error) {
-  if (response) {
-    // Successful response received
-  } else {
-    // RPC error
-  }
-}];
-

As you can see, we create and populate a request protocol buffer object (in our -case RTGPoint). Then, we call the method on the service object, passing it the -request, and a block to handle the response (or any RPC error). If the RPC -finishes successfully, the handler block is called with a nil error argument, -and we can read the response information from the server from the response -argument. If, instead, some RPC error happens, the handler block is called with -a nil response argument, and we can read the details of the problem from the -error argument.

-
NSLog(@"Found feature called %@ at %@.", response.name, response.location);
-
Streaming RPCs
- -

Now let’s look at our streaming methods. Here’s where we call the -response-streaming method ListFeatures, which results in our client app -receiving a stream of geographical RTGFeatures:

-
[service listFeaturesWithRequest:rectangle
-                    eventHandler:^(BOOL done, RTGFeature *response, NSError *error) {
-  if (response) {
-    NSLog(@"Found feature at %@ called %@.", response.location, response.name);
-  } else if (error) {
-    NSLog(@"RPC error: %@", error);
-  }
-}];
-

Notice how the signature of the handler block now includes a BOOL done -parameter. The handler block can be called any number of times; only on the last -call is the done argument value set to YES. If an error occurs, the RPC -finishes and the handler is called with the arguments (YES, nil, error).

- -

The request-streaming method RecordRoute expects a stream of RTGPoints from -the cient. This stream is passed to the method as an object that conforms to the -GRXWriter protocol. The simplest way to create one is to initialize one from a -NSArray object:

-
#import <gRPC/GRXWriter+Immediate.h>
-
-...
-
-RTGPoint *point1 = [RTGPoint message];
-point.latitude = 40E7;
-point.longitude = -74E7;
-
-RTGPoint *point2 = [RTGPoint message];
-point.latitude = 40E7;
-point.longitude = -74E7;
-
-GRXWriter *locationsWriter = [GRXWriter writerWithContainer:@[point1, point2]];
-
-[service recordRouteWithRequestsWriter:locationsWriter handler:^(RTGRouteSummary *response, NSError *error) {
-  if (response) {
-    NSLog(@"Finished trip with %i points", response.pointCount);
-    NSLog(@"Passed %i features", response.featureCount);
-    NSLog(@"Travelled %i meters", response.distance);
-    NSLog(@"It took %i seconds", response.elapsedTime);
-  } else {
-    NSLog(@"RPC error: %@", error);
-  }
-}];
-

The GRXWriter protocol is generic enough to allow for asynchronous streams, streams of future values, or even infinite streams.

- -

Finally, let’s look at our bidirectional streaming RPC RouteChat(). The way to -call a bidirectional streaming RPC is just a combination of how to call -request-streaming RPCs and response-streaming RPCs.

-
[service routeChatWithRequestsWriter:notesWriter handler:^(BOOL done, RTGRouteNote *note, NSError *error) {
-  if (note) {
-    NSLog(@"Got message %@ at %@", note.message, note.location);
-  } else if (error) {
-    NSLog(@"RPC error: %@", error);
-  }
-  if (done) {
-    NSLog(@"Chat ended.");
-  }
-}];
-

The semantics for the handler block and the GRXWriter argument here are -exactly the same as for our request-streaming and response-streaming methods. -Although both client and server will always get the other’s messages in the -order they were written, the two streams operate completely independently.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/php.html b/public/docs/tutorials/basic/php.html deleted file mode 100644 index 46ee949..0000000 --- a/public/docs/tutorials/basic/php.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/php/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/php/index.html b/public/docs/tutorials/basic/php/index.html deleted file mode 100644 index 1a30665..0000000 --- a/public/docs/tutorials/basic/php/index.html +++ /dev/null @@ -1,447 +0,0 @@ - - - - - - - - - - - - gRPC Basics - PHP – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - PHP

- - - -

This tutorial provides a basic PHP programmer’s introduction to -working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes a passing familiarity with protocol -buffers. Note -that the example in this tutorial uses the proto2 version of the protocol -buffers language.

- -

Also note that currently you can only create clients in PHP for gRPC services - -you can find out how to create gRPC servers in our other tutorials, e.g. -Node.js.

- -
- -

- -

Why use gRPC?

- -

With gRPC you can define your service once in a .proto file and implement -clients and servers in any of gRPC’s supported languages, which in turn can be -run in environments ranging from servers inside Google to your own tablet - all -the complexity of communication between different languages and environments is -handled for you by gRPC. You also get all the advantages of working with -protocol buffers, including efficient serialization, a simple IDL, and easy -interface updating.

- -

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/php/route_guide. -To download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-

You need grpc-php-plugin to help you generate proto files. You can build it from source:

-
$ cd grpc && git submodule update --init && make grpc_php_plugin
-

Then change your current directory to examples/php/route_guide and generate proto files:

-
$ cd examples/php/route_guide
-$ ./route_guide_proto_gen.sh
-

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

You also should have the relevant tools installed to generate the client -interface code (and a server in another language, for testing). You can obtain -the latter by following these setup -instructions.

- -

- -

Try it out!

- -

To try the sample app, we need a gRPC server running locally. Let’s compile and -run, for example, the Node.js server in this repository:

-
$ cd ../../node
-$ npm install
-$ cd dynamic_codegen/route_guide
-$ nodejs ./route_guide_server.js --db_path=route_guide_db.json
-

Run the PHP client (in a different terminal):

-
$ ./run_route_guide_client.sh
-

The next sections guide you step-by-step through how this proto service is -defined, how to generate a client library from it, and how to create a client -stub that uses that library.

- -

- -

Defining the service

- -

First let’s look at how the service we’re using is defined. A gRPC service and -its method request and response types using protocol -buffers. You can -see the complete .proto file for our example in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. Protocol buffers let you define four kinds of -service method, all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

- -

Generating client code

- -

The PHP client stub implementation of the proto files can be generated by the -gRPC PHP Protoc Plugin. To compile the plugin:

-
$ make grpc_php_plugin
-

To generate the client stub implementation .php file:

-
$ cd grpc
-$ protoc --proto_path=examples/protos \
-  --php_out=examples/php/route_guide \
-  --grpc_out=examples/php/route_guide \
-  --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \
-  ./examples/protos/route_guide.proto
-

or running the helper script under the grpc/example/php/route_guide directory if you build -grpc-php-plugin by source:

-
$ ./route_guide_proto_gen.sh
-

A number of files will be generated in the examples/php/route_guide directory. -You do not need to modify those files.

- -

To load these generated files, add this section to your composer.json file under -examples/php directory

-
  "autoload": {
-    "psr-4": {
-      "": "route_guide/"
-    }
-  }
-

The file contains:

- - - -

- -

Creating the client

- -

In this section, we’ll look at creating a PHP client for our RouteGuide -service. You can see our complete example client code in -examples/php/route_guide/route_guide_client.php.

- -

Constructing a client object

- -

To call service methods, we first need to create a client object, an instance of -the generated RouteGuideClient class. The constructor of the class expects the -server address and port we want to connect to:

-
$client = new Routeguide\RouteGuideClient('localhost:50051', [
-    'credentials' => Grpc\ChannelCredentials::createInsecure(),
-]);
-

Calling service methods

- -

Now let’s look at how we call our service methods.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local asynchronous method.

-
$point = new Routeguide\Point();
-$point->setLatitude(409146138);
-$point->setLongitude(-746188906);
-list($feature, $status) = $client->GetFeature($point)->wait();
-

As you can see, we create and populate a request object, i.e. an -Routeguide\Point object. Then, we call the method on the stub, passing it the -request object. If there is no error, then we can read the response information -from the server from our response object, i.e. an Routeguide\Feature object.

-
print sprintf("Found %s \n  at %f, %f\n", $feature->getName(),
-              $feature->getLocation()->getLatitude() / COORD_FACTOR,
-              $feature->getLocation()->getLongitude() / COORD_FACTOR);
-
Streaming RPCs
- -

Now let’s look at our streaming methods. Here’s where we call the server-side -streaming method ListFeatures, which returns a stream of geographical -Features:

-
$lo_point = new Routeguide\Point();
-$hi_point = new Routeguide\Point();
-
-$lo_point->setLatitude(400000000);
-$lo_point->setLongitude(-750000000);
-$hi_point->setLatitude(420000000);
-$hi_point->setLongitude(-730000000);
-
-$rectangle = new Routeguide\Rectangle();
-$rectangle->setLo($lo_point);
-$rectangle->setHi($hi_point);
-
-$call = $client->ListFeatures($rectangle);
-// an iterator over the server streaming responses
-$features = $call->responses();
-foreach ($features as $feature) {
-  // process each feature
-} // the loop will end when the server indicates there is no more responses to be sent.
-

The $call->responses() method call returns an iterator. When the server sends -a response, a $feature object will be returned in the foreach loop, until -the server indiciates that there will be no more responses to be sent.

- -

The client-side streaming method RecordRoute is similar, except that we call -$call->write($point) for each point we want to write from the client side and -get back a Routeguide\RouteSummary.

-
$call = $client->RecordRoute();
-
-for ($i = 0; $i < $num_points; $i++) {
-  $point = new Routeguide\Point();
-  $point->setLatitude($lat);
-  $point->setLongitude($long);
-  $call->write($point);
-}
-
-list($route_summary, $status) = $call->wait();
-

Finally, let’s look at our bidirectional streaming RPC routeChat(). In this -case, we just pass a context to the method and get back a BidiStreamingCall -stream object, which we can use to both write and read messages.

-
$call = $client->RouteChat();
-

To write messages from the client:

-
foreach ($notes as $n) {
-  $route_note = new Routeguide\RouteNote();
-  $call->write($route_note);
-}
-$call->writesDone();
-

To read messages from the server:

-
while ($route_note_reply = $call->read()) {
-  // process $route_note_reply
-}
-

Each side will always get the other’s messages in the order they were written, -both the client and server can read and write in any order — the streams operate -completely independently.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/python.html b/public/docs/tutorials/basic/python.html deleted file mode 100644 index 7432113..0000000 --- a/public/docs/tutorials/basic/python.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/python/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/python/index.html b/public/docs/tutorials/basic/python/index.html deleted file mode 100644 index 5ed8c94..0000000 --- a/public/docs/tutorials/basic/python/index.html +++ /dev/null @@ -1,496 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Python – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Python

- - - -

This tutorial provides a basic Python programmer’s introduction -to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol -buffers. You can -find out more in the proto3 language -guide and Python -generated code -guide.

- -
- -

Why use gRPC?

- -

This example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC you can define your service once in a .proto file and implement -clients and servers in any of gRPC’s supported languages, which in turn can be -run in environments ranging from servers inside Google to your own tablet - -all the complexity of communication between different languages and environments -is handled for you by gRPC. You also get all the advantages of working with -protocol buffers, including efficient serialization, a simple IDL, and easy -interface updating.

- -

Example code and setup

- -

The example code for this tutorial is in -grpc/grpc/examples/python/route_guide. -To download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-

Then change your current directory to examples/python/route_guide in the repository:

-
$ cd grpc/examples/python/route_guide
-

You also should have the relevant tools installed to generate the server and -client interface code - if you don’t already, follow the setup instructions in -the Python quick start guide.

- -

Defining the service

- -

Your first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol -buffers. You can -see the complete .proto file in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   // (Method definitions not shown)
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Your .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next you need to generate the gRPC client and server interfaces from your .proto -service definition.

- -

First, install the grpcio-tools package:

-
$ pip install grpcio-tools
-

Use the following command to generate the Python code:

-
$ python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/route_guide.proto
-

Note that as we’ve already provided a version of the generated code in the -example directory, running this command regenerates the appropriate file rather -than creates a new one. The generated code files are called -route_guide_pb2.py and route_guide_pb2_grpc.py and contain:

- - - -

Note: The 2 in pb2 indicates that the generated code is following Protocol Buffers Python API version 2. Version 1 is obsolete. It has no relation to the Protocol Buffers Language version, which is the one indicated by syntax = "proto3" or syntax = "proto2" in a .proto file.

- -

- -

Creating the server

- -

First let’s look at how you create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

Creating and running a RouteGuide server breaks down into two work items: -- Implementing the servicer interface generated from our service definition with - functions that perform the actual “work” of the service. -- Running a gRPC server to listen for requests from clients and transmit - responses.

- -

You can find the example RouteGuide server in -examples/python/route_guide/route_guide_server.py.

- -

Implementing RouteGuide

- -

route_guide_server.py has a RouteGuideServicer class that subclasses the -generated class route_guide_pb2_grpc.RouteGuideServicer:

-
# RouteGuideServicer provides an implementation of the methods of the RouteGuide service.
-class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
-

RouteGuideServicer implements all the RouteGuide service methods.

- -
Simple RPC
- -

Let’s look at the simplest type first, GetFeature, which just gets a Point -from the client and returns the corresponding feature information from its -database in a Feature.

-
def GetFeature(self, request, context):
-  feature = get_feature(self.db, request)
-  if feature is None:
-    return route_guide_pb2.Feature(name="", location=request)
-  else:
-    return feature
-

The method is passed a route_guide_pb2.Point request for the RPC, and a -grpc.ServicerContext object that provides RPC-specific information such as -timeout limits. It returns a route_guide_pb2.Feature response.

- -
Response-streaming RPC
- -

Now let’s look at the next method. ListFeatures is a response-streaming RPC -that sends multiple Features to the client.

-
def ListFeatures(self, request, context):
-  left = min(request.lo.longitude, request.hi.longitude)
-  right = max(request.lo.longitude, request.hi.longitude)
-  top = max(request.lo.latitude, request.hi.latitude)
-  bottom = min(request.lo.latitude, request.hi.latitude)
-  for feature in self.db:
-    if (feature.location.longitude >= left and
-        feature.location.longitude <= right and
-        feature.location.latitude >= bottom and
-        feature.location.latitude <= top):
-      yield feature
-

Here the request message is a route_guide_pb2.Rectangle within which the -client wants to find Features. Instead of returning a single response the -method yields zero or more responses.

- -
Request-streaming RPC
- -

The request-streaming method RecordRoute uses an -iterator of -request values and returns a single response value.

-
def RecordRoute(self, request_iterator, context):
-  point_count = 0
-  feature_count = 0
-  distance = 0.0
-  prev_point = None
-
-  start_time = time.time()
-  for point in request_iterator:
-    point_count += 1
-    if get_feature(self.db, point):
-      feature_count += 1
-    if prev_point:
-      distance += get_distance(prev_point, point)
-    prev_point = point
-
-  elapsed_time = time.time() - start_time
-  return route_guide_pb2.RouteSummary(point_count=point_count,
-                                      feature_count=feature_count,
-                                      distance=int(distance),
-                                      elapsed_time=int(elapsed_time))
-
Bidirectional streaming RPC
- -

Lastly let’s look at the bidirectionally-streaming method RouteChat.

-
def RouteChat(self, request_iterator, context):
-  prev_notes = []
-  for new_note in request_iterator:
-    for prev_note in prev_notes:
-      if prev_note.location == new_note.location:
-        yield prev_note
-    prev_notes.append(new_note)
-

This method’s semantics are a combination of those of the request-streaming -method and the response-streaming method. It is passed an iterator of request -values and is itself an iterator of response values.

- -

Starting the server

- -

Once you have implemented all the RouteGuide methods, the next step is to -start up a gRPC server so that clients can actually use your service:

-
def serve():
-  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
-  route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
-      RouteGuideServicer(), server)
-  server.add_insecure_port('[::]:50051')
-  server.start()
-

Because start() does not block you may need to sleep-loop if there is nothing -else for your code to do while serving.

- -

- -

Creating the client

- -

You can see the complete example client code in -examples/python/route_guide/route_guide_client.py.

- -

Creating a stub

- -

To call service methods, we first need to create a stub.

- -

We instantiate the RouteGuideStub class of the route_guide_pb2_grpc -module, generated from our .proto.

-
channel = grpc.insecure_channel('localhost:50051')
-stub = route_guide_pb2_grpc.RouteGuideStub(channel)
-

Calling service methods

- -

For RPC methods that return a single response (“response-unary” methods), gRPC -Python supports both synchronous (blocking) and asynchronous (non-blocking) -control flow semantics. For response-streaming RPC methods, calls immediately -return an iterator of response values. Calls to that iterator’s next() method -block until the response to be yielded from the iterator becomes available.

- -
Simple RPC
- -

A synchronous call to the simple RPC GetFeature is nearly as straightforward -as calling a local method. The RPC call waits for the server to respond, and -will either return a response or raise an exception:

-
feature = stub.GetFeature(point)
-

An asynchronous call to GetFeature is similar, but like calling a local method -asynchronously in a thread pool:

-
feature_future = stub.GetFeature.future(point)
-feature = feature_future.result()
-
Response-streaming RPC
- -

Calling the response-streaming ListFeatures is similar to working with -sequence types:

-
for feature in stub.ListFeatures(rectangle):
-
Request-streaming RPC
- -

Calling the request-streaming RecordRoute is similar to passing an iterator -to a local method. Like the simple RPC above that also returns a single -response, it can be called synchronously or asynchronously:

-
route_summary = stub.RecordRoute(point_iterator)
route_summary_future = stub.RecordRoute.future(point_iterator)
-route_summary = route_summary_future.result()
-
Bidirectional streaming RPC
- -

Calling the bidirectionally-streaming RouteChat has (as is the case on the -service-side) a combination of the request-streaming and response-streaming -semantics:

-
for received_route_note in stub.RouteChat(sent_route_note_iterator):
-

Try it out!

- -

Run the server, which will listen on port 50051:

-
$ python route_guide_server.py
-

Run the client (in a different terminal):

-
$ python route_guide_client.py
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/ruby.html b/public/docs/tutorials/basic/ruby.html deleted file mode 100644 index 56d40f5..0000000 --- a/public/docs/tutorials/basic/ruby.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/ruby/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/ruby/index.html b/public/docs/tutorials/basic/ruby/index.html deleted file mode 100644 index ad1e6f1..0000000 --- a/public/docs/tutorials/basic/ruby/index.html +++ /dev/null @@ -1,507 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Ruby – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Ruby

- - - -

This tutorial provides a basic Ruby programmer’s introduction to working with gRPC.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes that you have read the Overview and are familiar -with protocol -buffers. Note -that the example in this tutorial uses the proto3 version of the protocol -buffers language: you can find out more in -the proto3 language -guide.

- -
- -

Why use gRPC?

- -

Our example is a simple route mapping application that lets clients get -information about features on their route, create a summary of their route, and -exchange route information such as traffic updates with the server and other -clients.

- -

With gRPC we can define our service once in a .proto file and implement clients -and servers in any of gRPC’s supported languages, which in turn can be run in -environments ranging from servers inside Google to your own tablet - all the -complexity of communication between different languages and environments is -handled for you by gRPC. We also get all the advantages of working with protocol -buffers, including efficient serialization, a simple IDL, and easy interface -updating.

- -

Example code and setup

- -

The example code for our tutorial is in -grpc/grpc/examples/ruby/route_guide. -To download the example, clone the grpc repository by running the following -command:

-
$ git clone -b v1.20.0 https://github.com/grpc/grpc
-$ cd grpc
-

Then change your current directory to examples/ruby/route_guide:

-
$ cd examples/ruby/route_guide
-

You also should have the relevant tools installed to generate the server and -client interface code - if you don’t already, follow the setup instructions in -the Ruby quick start guide.

- -

Defining the service

- -

Our first step (as you’ll know from the Overview) is to -define the gRPC service and the method request and response types using -protocol -buffers. You can -see the complete .proto file in -examples/protos/route_guide.proto.

- -

To define a service, you specify a named service in your .proto file:

-
service RouteGuide {
-   ...
-}
-

Then you define rpc methods inside your service definition, specifying their -request and response types. gRPC lets you define four kinds of service method, -all of which are used in the RouteGuide service:

- - -
// Obtains the feature at a given position.
-rpc GetFeature(Point) returns (Feature) {}
- -
// Obtains the Features available within the given Rectangle.  Results are
-// streamed rather than returned at once (e.g. in a response message with a
-// repeated field), as the rectangle may cover a large area and contain a
-// huge number of features.
-rpc ListFeatures(Rectangle) returns (stream Feature) {}
- -
// Accepts a stream of Points on a route being traversed, returning a
-// RouteSummary when traversal is completed.
-rpc RecordRoute(stream Point) returns (RouteSummary) {}
- -
// Accepts a stream of RouteNotes sent while a route is being traversed,
-// while receiving other RouteNotes (e.g. from other users).
-rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
-

Our .proto file also contains protocol buffer message type definitions for all -the request and response types used in our service methods - for example, here’s -the Point message type:

-
// Points are represented as latitude-longitude pairs in the E7 representation
-// (degrees multiplied by 10**7 and rounded to the nearest integer).
-// Latitudes should be in the range +/- 90 degrees and longitude should be in
-// the range +/- 180 degrees (inclusive).
-message Point {
-  int32 latitude = 1;
-  int32 longitude = 2;
-}
-

Generating client and server code

- -

Next we need to generate the gRPC client and server interfaces from our .proto -service definition. We do this using the protocol buffer compiler protoc with -a special gRPC Ruby plugin.

- -

If you want to run this yourself, make sure you’ve installed protoc and followed -the gRPC Ruby plugin installation -instructions first):

- -

Once that’s done, the following command can be used to generate the ruby code.

-
$ grpc_tools_ruby_protoc -I ../../protos --ruby_out=../lib --grpc_out=../lib ../../protos/route_guide.proto
-

Running this command regenerates the following files in the lib directory:

- - - -

- -

Creating the server

- -

First let’s look at how we create a RouteGuide server. If you’re only -interested in creating gRPC clients, you can skip this section and go straight -to Creating the client (though you might find it interesting -anyway!).

- -

There are two parts to making our RouteGuide service do its job: -- Implementing the service interface generated from our service definition: - doing the actual “work” of our service. -- Running a gRPC server to listen for requests from clients and return the - service responses.

- -

You can find our example RouteGuide server in -examples/ruby/route_guide/route_guide_server.rb. -Let’s take a closer look at how it works.

- -

Implementing RouteGuide

- -

As you can see, our server has a ServerImpl class that extends the generated -RouteGuide::Service:

-
# ServerImpl provides an implementation of the RouteGuide service.
-class ServerImpl < RouteGuide::Service
-

ServerImpl implements all our service methods. Let’s look at the simplest type -first, GetFeature, which just gets a Point from the client and returns the -corresponding feature information from its database in a Feature.

-
def get_feature(point, _call)
-  name = @feature_db[{
-    'longitude' => point.longitude,
-    'latitude' => point.latitude }] || ''
-  Feature.new(location: point, name: name)
-end
-

The method is passed a _call for the RPC, the client’s Point protocol buffer -request, and returns a Feature protocol buffer. In the method we create the -Feature with the appropriate information, and then return it.

- -

Now let’s look at something a bit more complicated - a streaming RPC. -ListFeatures is a server-side streaming RPC, so we need to send back multiple -Features to our client.

-
# in ServerImpl
-
-  def list_features(rectangle, _call)
-    RectangleEnum.new(@feature_db, rectangle).each
-  end
-

As you can see, here the request object is a Rectangle in which our client -wants to find Features, but instead of returning a simple response we need to -return an Enumerator that -yields the responses. In the method, we use a helper class RectangleEnum, to -act as an Enumerator implementation.

- -

Similarly, the client-side streaming method record_route uses an -Enumerable, but here it’s -obtained from the call object, which we’ve ignored in the earlier examples. -call.each_remote_read yields each message sent by the client in turn.

-
call.each_remote_read do |point|
-  ...
-end
-

Finally, let’s look at our bidirectional streaming RPC route_chat.

-
def route_chat(notes)
-  q = EnumeratorQueue.new(self)
-  t = Thread.new do
-    begin
-      notes.each do |n|
-      	...
-    end
-      end
-  q = EnumeratorQueue.new(self)
-...
-  return q.each_item
-end
-

Here the method receives an -Enumerable, but also returns -an Enumerator that yields the -responses. The implementation demonstrates how to set these up so that the -requests and responses can be handled concurrently. Although each side will -always get the other’s messages in the order they were written, both the client -and server can read and write in any order — the streams operate completely -independently.

- -

Starting the server

- -

Once we’ve implemented all our methods, we also need to start up a gRPC server -so that clients can actually use our service. The following snippet shows how we -do this for our RouteGuide service:

-
addr = "0.0.0.0:8080"
-s = GRPC::RpcServer.new
-s.add_http2_port(addr, :this_port_is_insecure)
-logger.info("... running insecurely on #{addr}")
-s.handle(ServerImpl.new(feature_db))
-s.run_till_terminated
-

As you can see, we build and start our server using a GRPC::RpcServer. To do -this, we:

- -
    -
  1. Create an instance of our service implementation class ServerImpl.
  2. -
  3. Specify the address and port we want to use to listen for client requests -using the builder’s add_http2_port method.
  4. -
  5. Register our service implementation with the GRPC::RpcServer.
  6. -
  7. Call run on theGRPC::RpcServer to create and start an RPC server for our -service.
  8. -
- -

- -

Creating the client

- -

In this section, we’ll look at creating a Ruby client for our RouteGuide -service. You can see our complete example client code in -examples/ruby/route_guide/route_guide_client.rb.

- -

Creating a stub

- -

To call service methods, we first need to create a stub.

- -

We use the Stub class of the RouteGuide module generated from our .proto.

-
stub = RouteGuide::Stub.new('localhost:50051')
-

Calling service methods

- -

Now let’s look at how we call our service methods. Note that the gRPC Ruby only -provides blocking/synchronous versions of each method: this means that the -RPC call waits for the server to respond, and will either return a response or -raise an exception.

- -
Simple RPC
- -

Calling the simple RPC GetFeature is nearly as straightforward as calling a -local method.

-
GET_FEATURE_POINTS = [
-  Point.new(latitude:  409_146_138, longitude: -746_188_906),
-  Point.new(latitude:  0, longitude: 0)
-]
-..
-  GET_FEATURE_POINTS.each do |pt|
-    resp = stub.get_feature(pt)
-	...
-    p "- found '#{resp.name}' at #{pt.inspect}"
-  end
-

As you can see, we create and populate a request protocol buffer object (in our -case Point), and create a response protocol buffer object for the server to -fill in. Finally, we call the method on the stub, passing it the context, -request, and response. If the method returns OK, then we can read the response -information from the server from our response object.

- -
Streaming RPCs
- -

Now let’s look at our streaming methods. If you’ve already read Creating the -server some of this may look very familiar - streaming RPCs are -implemented in a similar way on both sides. Here’s where we call the server-side -streaming method list_features, which returns an Enumerable of Features

-
resps = stub.list_features(LIST_FEATURES_RECT)
-resps.each do |r|
-  p "- found '#{r.name}' at #{r.location.inspect}"
-end
-

The client-side streaming method record_route is similar, except there we pass -the server an Enumerable.

-
...
-reqs = RandomRoute.new(features, points_on_route)
-resp = stub.record_route(reqs.each, deadline)
-...
-

Finally, let’s look at our bidirectional streaming RPC route_chat. In this -case, we pass Enumerable to the method and get back an Enumerable.

-
resps = stub.route_chat(ROUTE_CHAT_NOTES)
-resps.each { |r| p "received #{r.inspect}" }
-

Although it’s not shown well by this example, each enumerable is independent of -the other - both the client and server can read and write in any order — the -streams operate completely independently.

- -

Try it out!

- -

Build client and server:

-
$ # from examples/ruby
-$ gem install bundler && bundle install
-

Run the server, which will listen on port 50051:

-
$ # from examples/ruby
-$ bundle exec route_guide/route_guide_server.rb ../python/route_guide/route_guide_db.json
-$ # (note that the route_guide_db.json file is actually language-agnostic; it's just
-$ # located in the python folder).
-

Run the client (in a different terminal):

-
$ # from examples/ruby
-$ bundle exec route_guide/route_guide_client.rb ../python/route_guide/route_guide_db.json
-
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/basic/web.html b/public/docs/tutorials/basic/web.html deleted file mode 100644 index 9b7c885..0000000 --- a/public/docs/tutorials/basic/web.html +++ /dev/null @@ -1 +0,0 @@ -https://cjyabraham.github.io/docs/tutorials/basic/web/ \ No newline at end of file diff --git a/public/docs/tutorials/basic/web/index.html b/public/docs/tutorials/basic/web/index.html deleted file mode 100644 index fa2ff9d..0000000 --- a/public/docs/tutorials/basic/web/index.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - - - - - - - - - gRPC Basics - Web – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

gRPC Basics - Web

- - - -

This tutorial provides a basic introduction on how to use -gRPC-Web from browsers.

- -

By walking through this example you’ll learn how to:

- - - -

It assumes a passing familiarity with protocol -buffers.

- -
- -

- -

Why use gRPC and gRPC-Web?

- -

With gRPC you can define your service once in a .proto file and implement -clients and servers in any of gRPC’s supported languages, which in turn can be -run in environments ranging from servers inside Google to your own tablet - all -the complexity of communication between different languages and environments is -handled for you by gRPC. You also get all the advantages of working with -protocol buffers, including efficient serialization, a simple IDL, and easy -interface updating. gRPC-Web lets you access gRPC services built in this manner -from browsers using an idiomatic API.

- -

- -

Define the Service

- -

The first step when creating a gRPC service is to define the service methods -and their request and response message types using protocol buffers. In this -example, we define our EchoService in a file called -echo.proto. -For more information about protocol buffers and proto3 syntax, please see the -protobuf documentation.

-
message EchoRequest {
-  string message = 1;
-}
-
-message EchoResponse {
-  string message = 1;
-}
-
-service EchoService {
-  rpc Echo(EchoRequest) returns (EchoResponse);
-}
-

Implement gRPC Backend Server

- -

Next, we implement our EchoService interface using Node in the backend gRPC -EchoServer. This will handle requests from clients. See the file -node-server/server.js -for details.

- -

You can implement the server in any language supported by gRPC. Please see -the main page for more details.

-
function doEcho(call, callback) {
-  callback(null, {message: call.request.message});
-}
-
-

Configure the Envoy Proxy

- -

In this example, we will use the Envoy -proxy to forward the gRPC browser request to the backend server. You can see -the complete config file in -envoy.yaml

- -

To forward the gRPC requests to the backend server, we need a block like -this:

-
  listeners:
-  - name: listener_0
-    address:
-      socket_address: { address: 0.0.0.0, port_value: 8080 }
-    filter_chains:
-    - filters:
-      - name: envoy.http_connection_manager
-        config:
-          codec_type: auto
-          stat_prefix: ingress_http
-          route_config:
-            name: local_route
-            virtual_hosts:
-            - name: local_service
-              domains: ["*"]
-              routes:
-              - match: { prefix: "/" }
-                route: { cluster: echo_service }
-          http_filters:
-          - name: envoy.grpc_web
-          - name: envoy.router
-  clusters:
-  - name: echo_service
-    connect_timeout: 0.25s
-    type: logical_dns
-    http2_protocol_options: {}
-    lb_policy: round_robin
-    hosts: [{ socket_address: { address: node-server, port_value: 9090 }}]
-

You may also need to add some CORS setup to make sure the browser can request -cross-origin content.

- -

In this simple example, the browser makes gRPC requests to port :8080. Envoy -forwards the request to the backend gRPC server listening on port :9090.

- -

Generate Protobuf Messages and Service Client Stub

- -

To generate the protobuf message classes from our echo.proto, run the -following command:

-
$ protoc -I=$DIR echo.proto \
-  --js_out=import_style=commonjs:$OUT_DIR
-

The import_style option passed to the --js_out flag makes sure the -generated files will have CommonJS style require() statements.

- -

To generate the gRPC-Web service client stub, first you need the gRPC-Web -protoc plugin. To compile the plugin protoc-gen-grpc-web, you need to run -this from the repo’s root directory:

-
$ cd grpc-web
-$ sudo make install-plugin
-

To generate the service client stub file, run this command:

-
$ protoc -I=$DIR echo.proto \
-  --grpc-web_out=import_style=commonjs,mode=grpcwebtext:$OUT_DIR
-

In the --grpc-web_out param above: - - mode can be grpcwebtext (default) or grpcweb - - import_style can be closure (default) or commonjs

- -

Our command generates the client stub, by default, to the file -echo_grpc_web_pb.js.

- -

Write JS Client Code

- -

Now you are ready to write some JS client code. Put this in a client.js file.

-
const {EchoRequest, EchoResponse} = require('./echo_pb.js');
-const {EchoServiceClient} = require('./echo_grpc_web_pb.js');
-
-var echoService = new EchoServiceClient('http://localhost:8080');
-
-var request = new EchoRequest();
-request.setMessage('Hello World!');
-
-echoService.echo(request, {}, function(err, response) {
-  // ...
-});
-
-

You will need a package.json file

-
{
-  "name": "grpc-web-commonjs-example",
-  "dependencies": {
-    "google-protobuf": "^3.6.1",
-    "grpc-web": "^0.4.0"
-  },
-  "devDependencies": {
-    "browserify": "^16.2.2",
-    "webpack": "^4.16.5",
-    "webpack-cli": "^3.1.0"
-  }
-}
-

Compile the JS Library

- -

Finally, putting all these together, we can compile all the relevant JS files -into one single JS library that can be used in the browser.

-
$ npm install
-$ npx webpack client.js
-

Now embed dist/main.js into your project and see it in action!

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/index.html b/public/docs/tutorials/index.html deleted file mode 100644 index 189ca83..0000000 --- a/public/docs/tutorials/index.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - Tutorials – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
Documentation
-
-
-
- - - - -
- -
- -Tutorials -Async - C++ -Auth - Objective C -Basic -C++ -C# -Dart -Go -Java -Android Java -Node -Objective-C -PHP -Python -Ruby -Web - -
- -
-

Tutorials

- -

This section contains tutorials for each of our supported languages. They -introduce you to gRPC’s API and associated concepts, and the different RPC types -that are available. If you just want to dive straight in with a working example -first, see our Quickstarts.

- -

We also have a growing number of tutorials on follow-on topics, with more in the -pipeline.

- -
-
- - - - - - - - - - - - diff --git a/public/docs/tutorials/index.xml b/public/docs/tutorials/index.xml deleted file mode 100644 index 015f37c..0000000 --- a/public/docs/tutorials/index.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - Tutorials on gRPC - https://cjyabraham.github.io/docs/tutorials/ - Recent content in Tutorials on gRPC - Hugo -- gohugo.io - en-us - - - - - - Asynchronous Basics - C++ - https://cjyabraham.github.io/docs/tutorials/async/helloasync-cpp/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/async/helloasync-cpp/ - This tutorial shows you how to write a simple server and client in C++ using gRPC&rsquo;s asynchronous/non-blocking APIs. It assumes you are already familiar with writing simple synchronous gRPC code, as described in gRPC Basics: C++. The example used in this tutorial follows on from the basic Greeter example we used in the overview. You&rsquo;ll find it along with installation instructions in grpc/examples/cpp/helloworld. - Overview gRPC uses the CompletionQueue API for asynchronous operations. - - - - OAuth2 on gRPC - Objective-C - https://cjyabraham.github.io/docs/tutorials/auth/oauth2-objective-c/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/auth/oauth2-objective-c/ - This example demonstrates how to use OAuth2 on gRPC to make authenticated API calls on behalf of a user. -By walking through it you&rsquo;ll also learn how to use the Objective-C gRPC API to: - Initialize and configure a remote call object before the RPC is started. Set request metadata elements on a call, which are semantically equivalent to HTTP request headers. Read response metadata from a call, which is equivalent to HTTP response headers and trailers. - - - - gRPC Basics - Android Java - https://cjyabraham.github.io/docs/tutorials/basic/android/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/android/ - This tutorial provides a basic Android Java programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate client code using the protocol buffer compiler. Use the Java gRPC API to write a simple mobile client for your service. It assumes that you have read the Overview and are familiar with protocol buffers. This guide also does not cover anything on the server side. - - - - gRPC Basics - C# - https://cjyabraham.github.io/docs/tutorials/basic/csharp/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/csharp/ - This tutorial provides a basic C# programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the C# gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide and C# generated code reference. - - - - gRPC Basics - C++ - https://cjyabraham.github.io/docs/tutorials/basic/c/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/c/ - This tutorial provides a basic C++ programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the C++ gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide and C++ generated code guide. - - - - gRPC Basics - Dart - https://cjyabraham.github.io/docs/tutorials/basic/dart/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/dart/ - This tutorial provides a basic Dart programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the Dart gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide. - - - - gRPC Basics - Go - https://cjyabraham.github.io/docs/tutorials/basic/go/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/go/ - This tutorial provides a basic Go programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the Go gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide and the Go generated code guide. - - - - gRPC Basics - Java - https://cjyabraham.github.io/docs/tutorials/basic/java/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/java/ - This tutorial provides a basic Java programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the Java gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide and Java generated code guide. - - - - gRPC Basics - Node.js - https://cjyabraham.github.io/docs/tutorials/basic/node/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/node/ - This tutorial provides a basic Node.js programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Use the Node.js gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language. - - - - gRPC Basics - Objective-C - https://cjyabraham.github.io/docs/tutorials/basic/objective-c/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/objective-c/ - This tutorial provides a basic Objective-C programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate client code using the protocol buffer compiler. Use the Objective-C gRPC API to write a simple client for your service. It assumes a passing familiarity with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide and the Objective-C generated code guide. - - - - gRPC Basics - PHP - https://cjyabraham.github.io/docs/tutorials/basic/php/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/php/ - This tutorial provides a basic PHP programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate client code using the protocol buffer compiler. Use the PHP gRPC API to write a simple client for your service. It assumes a passing familiarity with protocol buffers. Note that the example in this tutorial uses the proto2 version of the protocol buffers language. - - - - gRPC Basics - Python - https://cjyabraham.github.io/docs/tutorials/basic/python/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/python/ - This tutorial provides a basic Python programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the Python gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. You can find out more in the proto3 language guide and Python generated code guide. - - - - gRPC Basics - Ruby - https://cjyabraham.github.io/docs/tutorials/basic/ruby/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/ruby/ - This tutorial provides a basic Ruby programmer&rsquo;s introduction to working with gRPC. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate server and client code using the protocol buffer compiler. Use the Ruby gRPC API to write a simple client and server for your service. It assumes that you have read the Overview and are familiar with protocol buffers. Note that the example in this tutorial uses the proto3 version of the protocol buffers language: you can find out more in the proto3 language guide. - - - - gRPC Basics - Web - https://cjyabraham.github.io/docs/tutorials/basic/web/ - Mon, 01 Jan 0001 00:00:00 +0000 - - https://cjyabraham.github.io/docs/tutorials/basic/web/ - This tutorial provides a basic introduction on how to use gRPC-Web from browsers. -By walking through this example you&rsquo;ll learn how to: - Define a service in a .proto file. Generate client code using the protocol buffer compiler. Use the gRPC-Web API to write a simple client for your service. It assumes a passing familiarity with protocol buffers. - -Why use gRPC and gRPC-Web? With gRPC you can define your service once in a . - - - - \ No newline at end of file diff --git a/public/faq/index.html b/public/faq/index.html deleted file mode 100644 index 3073466..0000000 --- a/public/faq/index.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - - - - - - - FAQ – gRPC - - - - - - - - - - - - - - - - - - -
-
-
- - - -
FAQ
-
-
-
- -
-
-
- - -
Here are some frequently asked questions. Hope you find your answer in here :-)
-

Frequently Asked Questions

-
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - - -
    - -
    - -
    - -
    - -
-
-
- -
- - - - - - - - - - diff --git a/public/favicons/android-chrome-192x192.png b/public/favicons/android-chrome-192x192.png deleted file mode 100755 index be0b649..0000000 Binary files a/public/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/public/favicons/apple-touch-icon.png b/public/favicons/apple-touch-icon.png deleted file mode 100755 index 7ffa7b5..0000000 Binary files a/public/favicons/apple-touch-icon.png and /dev/null differ diff --git a/public/favicons/browserconfig.xml b/public/favicons/browserconfig.xml deleted file mode 100755 index 4e40787..0000000 --- a/public/favicons/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #ffffff - - - diff --git a/public/favicons/favicon-16x16.png b/public/favicons/favicon-16x16.png deleted file mode 100755 index a50da68..0000000 Binary files a/public/favicons/favicon-16x16.png and /dev/null differ diff --git a/public/favicons/favicon-32x32.png b/public/favicons/favicon-32x32.png deleted file mode 100755 index b4b8ec3..0000000 Binary files a/public/favicons/favicon-32x32.png and /dev/null differ diff --git a/public/favicons/favicon.ico b/public/favicons/favicon.ico deleted file mode 100755 index c9882ae..0000000 Binary files a/public/favicons/favicon.ico and /dev/null differ diff --git a/public/favicons/manifest.json b/public/favicons/manifest.json deleted file mode 100755 index 4f3b90a..0000000 --- a/public/favicons/manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "grpc", - "icons": [ - { - "src": "\/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image\/png" - } - ], - "theme_color": "#ffffff", - "display": "standalone" -} diff --git a/public/favicons/mstile-150x150.png b/public/favicons/mstile-150x150.png deleted file mode 100755 index ab7edcf..0000000 Binary files a/public/favicons/mstile-150x150.png and /dev/null differ diff --git a/public/favicons/safari-pinned-tab.svg b/public/favicons/safari-pinned-tab.svg deleted file mode 100755 index b9af8d7..0000000 --- a/public/favicons/safari-pinned-tab.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - -Created by potrace 1.11, written by Peter Selinger 2001-2013 - - - - - diff --git a/public/img/CoreOS.svg b/public/img/CoreOS.svg deleted file mode 100644 index af5c6f4..0000000 Binary files a/public/img/CoreOS.svg and /dev/null differ diff --git a/public/img/arrow.svg b/public/img/arrow.svg deleted file mode 100755 index ee6e475..0000000 --- a/public/img/arrow.svg +++ /dev/null @@ -1,251 +0,0 @@ - - - - - - diff --git a/public/img/carbon.png b/public/img/carbon.png deleted file mode 100755 index 975ca12..0000000 Binary files a/public/img/carbon.png and /dev/null differ diff --git a/public/img/carbon3d.svg b/public/img/carbon3d.svg deleted file mode 100644 index d36fed5..0000000 --- a/public/img/carbon3d.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/public/img/caret-dark.svg b/public/img/caret-dark.svg deleted file mode 100644 index 6bde9f3..0000000 --- a/public/img/caret-dark.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/public/img/caret.svg b/public/img/caret.svg deleted file mode 100644 index 4e30d6b..0000000 --- a/public/img/caret.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/public/img/channels_mapping_2.png b/public/img/channels_mapping_2.png deleted file mode 100644 index f4724a0..0000000 Binary files a/public/img/channels_mapping_2.png and /dev/null differ diff --git a/public/img/cisco.png b/public/img/cisco.png deleted file mode 100755 index e454c2c..0000000 Binary files a/public/img/cisco.png and /dev/null differ diff --git a/public/img/cisco.svg b/public/img/cisco.svg deleted file mode 100644 index 87aaaa5..0000000 --- a/public/img/cisco.svg +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/cockroach-1.png b/public/img/cockroach-1.png deleted file mode 100644 index cfb7032..0000000 Binary files a/public/img/cockroach-1.png and /dev/null differ diff --git a/public/img/cockroach-icon.png b/public/img/cockroach-icon.png deleted file mode 100644 index cfd45c8..0000000 Binary files a/public/img/cockroach-icon.png and /dev/null differ diff --git a/public/img/cockroach-labs.png b/public/img/cockroach-labs.png deleted file mode 100755 index 76dc9e4..0000000 Binary files a/public/img/cockroach-labs.png and /dev/null differ diff --git a/public/img/conn_stream_frame_mapping.png b/public/img/conn_stream_frame_mapping.png deleted file mode 100644 index 1cc0600..0000000 Binary files a/public/img/conn_stream_frame_mapping.png and /dev/null differ diff --git a/public/img/coreos-1.png b/public/img/coreos-1.png deleted file mode 100644 index a24ee53..0000000 Binary files a/public/img/coreos-1.png and /dev/null differ diff --git a/public/img/coreos-icon.png b/public/img/coreos-icon.png deleted file mode 100644 index ded8de2..0000000 Binary files a/public/img/coreos-icon.png and /dev/null differ diff --git a/public/img/coreos.png b/public/img/coreos.png deleted file mode 100755 index be05fee..0000000 Binary files a/public/img/coreos.png and /dev/null differ diff --git a/public/img/dns_to_load_balancer_mapping_3.png b/public/img/dns_to_load_balancer_mapping_3.png deleted file mode 100644 index e6fccaa..0000000 Binary files a/public/img/dns_to_load_balancer_mapping_3.png and /dev/null differ diff --git a/public/img/docker-icon.png b/public/img/docker-icon.png deleted file mode 100644 index a9c762f..0000000 Binary files a/public/img/docker-icon.png and /dev/null differ diff --git a/public/img/external-link-dark.svg b/public/img/external-link-dark.svg deleted file mode 100644 index 01fe497..0000000 --- a/public/img/external-link-dark.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/public/img/external-link-icon.png b/public/img/external-link-icon.png deleted file mode 100644 index f28dc01..0000000 Binary files a/public/img/external-link-icon.png and /dev/null differ diff --git a/public/img/external-link.svg b/public/img/external-link.svg deleted file mode 100644 index 93f8e38..0000000 --- a/public/img/external-link.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/public/img/footer-logo.png b/public/img/footer-logo.png deleted file mode 100644 index cfcb469..0000000 Binary files a/public/img/footer-logo.png and /dev/null differ diff --git a/public/img/gcp-icon.png b/public/img/gcp-icon.png deleted file mode 100644 index 851031e..0000000 Binary files a/public/img/gcp-icon.png and /dev/null differ diff --git a/public/img/github-dark.svg b/public/img/github-dark.svg deleted file mode 100644 index 481721d..0000000 --- a/public/img/github-dark.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/public/img/github-ribbon.svg b/public/img/github-ribbon.svg deleted file mode 100644 index 6eb67af..0000000 --- a/public/img/github-ribbon.svg +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/github.svg b/public/img/github.svg deleted file mode 100644 index 2833a91..0000000 --- a/public/img/github.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/public/img/graphic-04-mobile.svg b/public/img/graphic-04-mobile.svg deleted file mode 100644 index 28e712b..0000000 --- a/public/img/graphic-04-mobile.svg +++ /dev/null @@ -1 +0,0 @@ -graphic-04-mobile \ No newline at end of file diff --git a/public/img/graphic-04.svg b/public/img/graphic-04.svg deleted file mode 100644 index e51c99b..0000000 --- a/public/img/graphic-04.svg +++ /dev/null @@ -1 +0,0 @@ -graphic-04 \ No newline at end of file diff --git a/public/img/grpc-core-stack.svg b/public/img/grpc-core-stack.svg deleted file mode 100644 index 1791968..0000000 --- a/public/img/grpc-core-stack.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/img/grpc-design-slideshare.png b/public/img/grpc-design-slideshare.png deleted file mode 100644 index e6617e1..0000000 Binary files a/public/img/grpc-design-slideshare.png and /dev/null differ diff --git a/public/img/grpc-go-stack.svg b/public/img/grpc-go-stack.svg deleted file mode 100644 index 7ff50b3..0000000 --- a/public/img/grpc-go-stack.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/img/grpc-gray.svg b/public/img/grpc-gray.svg deleted file mode 100644 index 78a6f75..0000000 --- a/public/img/grpc-gray.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - -grpc -Created with Sketch. - - diff --git a/public/img/grpc-icon-1.png b/public/img/grpc-icon-1.png deleted file mode 100755 index 9d38e0c..0000000 Binary files a/public/img/grpc-icon-1.png and /dev/null differ diff --git a/public/img/grpc-icon-2.png b/public/img/grpc-icon-2.png deleted file mode 100755 index b2bc803..0000000 Binary files a/public/img/grpc-icon-2.png and /dev/null differ diff --git a/public/img/grpc-icon-3.png b/public/img/grpc-icon-3.png deleted file mode 100755 index 272a382..0000000 Binary files a/public/img/grpc-icon-3.png and /dev/null differ diff --git a/public/img/grpc-icon-4.png b/public/img/grpc-icon-4.png deleted file mode 100755 index 7fa57b1..0000000 Binary files a/public/img/grpc-icon-4.png and /dev/null differ diff --git a/public/img/grpc-intel-slideshare.png b/public/img/grpc-intel-slideshare.png deleted file mode 100644 index 2d63656..0000000 Binary files a/public/img/grpc-intel-slideshare.png and /dev/null differ diff --git a/public/img/grpc-java-stack.svg b/public/img/grpc-java-stack.svg deleted file mode 100644 index e08f66e..0000000 --- a/public/img/grpc-java-stack.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/img/grpc-logo.png b/public/img/grpc-logo.png deleted file mode 100755 index 3bad75e..0000000 Binary files a/public/img/grpc-logo.png and /dev/null differ diff --git a/public/img/grpc-logo.svg b/public/img/grpc-logo.svg deleted file mode 100755 index 532760f..0000000 --- a/public/img/grpc-logo.svg +++ /dev/null @@ -1,371 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/grpc-newicon-1.svg b/public/img/grpc-newicon-1.svg deleted file mode 100644 index e67a26d..0000000 --- a/public/img/grpc-newicon-1.svg +++ /dev/null @@ -1 +0,0 @@ -grpc-newicon-1 \ No newline at end of file diff --git a/public/img/grpc-newicon-2.svg b/public/img/grpc-newicon-2.svg deleted file mode 100644 index 7436c4c..0000000 --- a/public/img/grpc-newicon-2.svg +++ /dev/null @@ -1 +0,0 @@ -grpc-newicon-2 \ No newline at end of file diff --git a/public/img/grpc-newicon-3.svg b/public/img/grpc-newicon-3.svg deleted file mode 100644 index 0222aab..0000000 --- a/public/img/grpc-newicon-3.svg +++ /dev/null @@ -1 +0,0 @@ -grpc-newicon-3 \ No newline at end of file diff --git a/public/img/grpc-newicon-4.svg b/public/img/grpc-newicon-4.svg deleted file mode 100644 index ae03e4c..0000000 --- a/public/img/grpc-newicon-4.svg +++ /dev/null @@ -1 +0,0 @@ -grpc-newicon-4 \ No newline at end of file diff --git a/public/img/grpc-overview-slideshare.png b/public/img/grpc-overview-slideshare.png deleted file mode 100644 index 848212e..0000000 Binary files a/public/img/grpc-overview-slideshare.png and /dev/null differ diff --git a/public/img/grpc-rest-gateway.png b/public/img/grpc-rest-gateway.png deleted file mode 100644 index 6323717..0000000 Binary files a/public/img/grpc-rest-gateway.png and /dev/null differ diff --git a/public/img/grpc-swaggerscreen.png b/public/img/grpc-swaggerscreen.png deleted file mode 100644 index 431659a..0000000 Binary files a/public/img/grpc-swaggerscreen.png and /dev/null differ diff --git a/public/img/grpc-web-arch.png b/public/img/grpc-web-arch.png deleted file mode 100644 index 7447d5d..0000000 Binary files a/public/img/grpc-web-arch.png and /dev/null differ diff --git a/public/img/grpc-web-proxy.png b/public/img/grpc-web-proxy.png deleted file mode 100644 index 21ace07..0000000 Binary files a/public/img/grpc-web-proxy.png and /dev/null differ diff --git a/public/img/grpc.svg b/public/img/grpc.svg deleted file mode 100644 index d5011f4..0000000 --- a/public/img/grpc.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - grpc - Created with Sketch. - - - \ No newline at end of file diff --git a/public/img/grpc_concept_diagram_00.png b/public/img/grpc_concept_diagram_00.png deleted file mode 100644 index e4a2c1b..0000000 Binary files a/public/img/grpc_concept_diagram_00.png and /dev/null differ diff --git a/public/img/grpc_inverse.svg b/public/img/grpc_inverse.svg deleted file mode 100644 index 66b1af6..0000000 --- a/public/img/grpc_inverse.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - grpc_white - Created with Sketch. - - - - - \ No newline at end of file diff --git a/public/img/grpc_on_http2_mapping_2.png b/public/img/grpc_on_http2_mapping_2.png deleted file mode 100644 index f536bb2..0000000 Binary files a/public/img/grpc_on_http2_mapping_2.png and /dev/null differ diff --git a/public/img/grpc_square_reverse_4x.png b/public/img/grpc_square_reverse_4x.png deleted file mode 100644 index aa2d903..0000000 Binary files a/public/img/grpc_square_reverse_4x.png and /dev/null differ diff --git a/public/img/hero-bg.png b/public/img/hero-bg.png deleted file mode 100644 index 82e1d0c..0000000 Binary files a/public/img/hero-bg.png and /dev/null differ diff --git a/public/img/http2_queue_3.png b/public/img/http2_queue_3.png deleted file mode 100644 index c853842..0000000 Binary files a/public/img/http2_queue_3.png and /dev/null differ diff --git a/public/img/http2_round_robin.png b/public/img/http2_round_robin.png deleted file mode 100644 index 1bbc6eb..0000000 Binary files a/public/img/http2_round_robin.png and /dev/null differ diff --git a/public/img/icon_github.svg b/public/img/icon_github.svg deleted file mode 100644 index 579effd..0000000 --- a/public/img/icon_github.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/public/img/icon_google-plus.svg b/public/img/icon_google-plus.svg deleted file mode 100644 index f9e90e5..0000000 --- a/public/img/icon_google-plus.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/public/img/icon_stack-overflow.svg b/public/img/icon_stack-overflow.svg deleted file mode 100644 index 7c8af60..0000000 --- a/public/img/icon_stack-overflow.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/public/img/icon_twitter.svg b/public/img/icon_twitter.svg deleted file mode 100644 index c1409e6..0000000 --- a/public/img/icon_twitter.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/public/img/icon_youtube.svg b/public/img/icon_youtube.svg deleted file mode 100644 index 66af5a1..0000000 --- a/public/img/icon_youtube.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - diff --git a/public/img/image_0.png b/public/img/image_0.png deleted file mode 100644 index 5c9b262..0000000 Binary files a/public/img/image_0.png and /dev/null differ diff --git a/public/img/image_1.png b/public/img/image_1.png deleted file mode 100644 index f443438..0000000 Binary files a/public/img/image_1.png and /dev/null differ diff --git a/public/img/image_2.png b/public/img/image_2.png deleted file mode 100644 index da4e884..0000000 Binary files a/public/img/image_2.png and /dev/null differ diff --git a/public/img/juniper.png b/public/img/juniper.png deleted file mode 100755 index 8c5bd4d..0000000 Binary files a/public/img/juniper.png and /dev/null differ diff --git a/public/img/juniperlogo.png b/public/img/juniperlogo.png deleted file mode 100644 index 57264eb..0000000 Binary files a/public/img/juniperlogo.png and /dev/null differ diff --git a/public/img/kotlin-project-android-app.png b/public/img/kotlin-project-android-app.png deleted file mode 100644 index 02a0778..0000000 Binary files a/public/img/kotlin-project-android-app.png and /dev/null differ diff --git a/public/img/landing-1.svg b/public/img/landing-1.svg deleted file mode 100644 index c99de71..0000000 --- a/public/img/landing-1.svg +++ /dev/null @@ -1,1197 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/landing-2.svg b/public/img/landing-2.svg deleted file mode 100644 index b2c9adb..0000000 --- a/public/img/landing-2.svg +++ /dev/null @@ -1,1196 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/landing-3.svg b/public/img/landing-3.svg deleted file mode 100644 index e51bc10..0000000 --- a/public/img/landing-3.svg +++ /dev/null @@ -1,1193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/landing-4.svg b/public/img/landing-4.svg deleted file mode 100644 index 2590a4d..0000000 --- a/public/img/landing-4.svg +++ /dev/null @@ -1,1192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/link-external.svg b/public/img/link-external.svg deleted file mode 100644 index 41e8151..0000000 --- a/public/img/link-external.svg +++ /dev/null @@ -1 +0,0 @@ -link-external \ No newline at end of file diff --git a/public/img/load_balance_round_robins_2.png b/public/img/load_balance_round_robins_2.png deleted file mode 100644 index bb182a6..0000000 Binary files a/public/img/load_balance_round_robins_2.png and /dev/null differ diff --git a/public/img/log.png b/public/img/log.png deleted file mode 100644 index 7691dc4..0000000 Binary files a/public/img/log.png and /dev/null differ diff --git a/public/img/logWithInfo.png b/public/img/logWithInfo.png deleted file mode 100644 index 3b55ead..0000000 Binary files a/public/img/logWithInfo.png and /dev/null differ diff --git a/public/img/mainpage.png b/public/img/mainpage.png deleted file mode 100644 index d381e49..0000000 Binary files a/public/img/mainpage.png and /dev/null differ diff --git a/public/img/more-arrow-dark.svg b/public/img/more-arrow-dark.svg deleted file mode 100644 index 5bea8eb..0000000 --- a/public/img/more-arrow-dark.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/public/img/more-arrow.png b/public/img/more-arrow.png deleted file mode 100644 index 375da35..0000000 Binary files a/public/img/more-arrow.png and /dev/null differ diff --git a/public/img/more-arrow.svg b/public/img/more-arrow.svg deleted file mode 100644 index a86b040..0000000 --- a/public/img/more-arrow.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/public/img/netflix-logo.png b/public/img/netflix-logo.png deleted file mode 100644 index d6b36f0..0000000 Binary files a/public/img/netflix-logo.png and /dev/null differ diff --git a/public/img/netflix.png b/public/img/netflix.png deleted file mode 100755 index 7381e5d..0000000 Binary files a/public/img/netflix.png and /dev/null differ diff --git a/public/img/netflix.svg b/public/img/netflix.svg deleted file mode 100644 index 361823c..0000000 --- a/public/img/netflix.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - diff --git a/public/img/pt-video-placeholder.png b/public/img/pt-video-placeholder.png deleted file mode 100644 index 5aa7c49..0000000 Binary files a/public/img/pt-video-placeholder.png and /dev/null differ diff --git a/public/img/socket8.png b/public/img/socket8.png deleted file mode 100644 index ecbe5df..0000000 Binary files a/public/img/socket8.png and /dev/null differ diff --git a/public/img/square-icon.png b/public/img/square-icon.png deleted file mode 100644 index 41b9910..0000000 Binary files a/public/img/square-icon.png and /dev/null differ diff --git a/public/img/square.png b/public/img/square.png deleted file mode 100755 index 50b31c7..0000000 Binary files a/public/img/square.png and /dev/null differ diff --git a/public/img/subChan4.png b/public/img/subChan4.png deleted file mode 100644 index a48d17b..0000000 Binary files a/public/img/subChan4.png and /dev/null differ diff --git a/public/img/subChan6_1.png b/public/img/subChan6_1.png deleted file mode 100644 index eedb5ac..0000000 Binary files a/public/img/subChan6_1.png and /dev/null differ diff --git a/public/img/subChan6_2.png b/public/img/subChan6_2.png deleted file mode 100644 index f19ee8f..0000000 Binary files a/public/img/subChan6_2.png and /dev/null differ diff --git a/public/img/target-pattern-syntax.png b/public/img/target-pattern-syntax.png deleted file mode 100644 index c45bb8e..0000000 Binary files a/public/img/target-pattern-syntax.png and /dev/null differ diff --git a/public/img/testing_framework.png b/public/img/testing_framework.png deleted file mode 100644 index c6e3f68..0000000 Binary files a/public/img/testing_framework.png and /dev/null differ diff --git a/public/img/topChan1.png b/public/img/topChan1.png deleted file mode 100644 index c3d9752..0000000 Binary files a/public/img/topChan1.png and /dev/null differ diff --git a/public/img/topChan2.png b/public/img/topChan2.png deleted file mode 100644 index be80c07..0000000 Binary files a/public/img/topChan2.png and /dev/null differ diff --git a/public/img/topChan3.png b/public/img/topChan3.png deleted file mode 100644 index 17775de..0000000 Binary files a/public/img/topChan3.png and /dev/null differ diff --git a/public/img/vend-icon.png b/public/img/vend-icon.png deleted file mode 100644 index ff0b0dc..0000000 Binary files a/public/img/vend-icon.png and /dev/null differ diff --git a/public/img/vendasta-icon.png b/public/img/vendasta-icon.png deleted file mode 100644 index 8cf2a8e..0000000 Binary files a/public/img/vendasta-icon.png and /dev/null differ diff --git a/public/img/vsco-logo.png b/public/img/vsco-logo.png deleted file mode 100644 index 89ec57d..0000000 Binary files a/public/img/vsco-logo.png and /dev/null differ diff --git a/public/img/wisc-mad.jpg b/public/img/wisc-mad.jpg deleted file mode 100644 index e3ffd27..0000000 Binary files a/public/img/wisc-mad.jpg and /dev/null differ diff --git a/public/img/wisconsin.png b/public/img/wisconsin.png deleted file mode 100755 index cb5d630..0000000 Binary files a/public/img/wisconsin.png and /dev/null differ diff --git a/public/img/x.svg b/public/img/x.svg deleted file mode 100644 index 2a4f410..0000000 --- a/public/img/x.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/public/img/yy-cpu-balanced.png b/public/img/yy-cpu-balanced.png deleted file mode 100644 index 43aa18c..0000000 Binary files a/public/img/yy-cpu-balanced.png and /dev/null differ diff --git a/public/img/yy-cpu-imbalance.png b/public/img/yy-cpu-imbalance.png deleted file mode 100644 index 936a943..0000000 Binary files a/public/img/yy-cpu-imbalance.png and /dev/null differ diff --git a/public/img/zlib-deps.png b/public/img/zlib-deps.png deleted file mode 100644 index 943524b..0000000 Binary files a/public/img/zlib-deps.png and /dev/null differ diff --git a/public/index.html b/public/index.html deleted file mode 100644 index a3d0a9d..0000000 --- a/public/index.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - gRPC - - - - - - - - - - - - - - - - - -
-
-
- - - - - -
A high performance, open-source universal RPC framework
- -
- -
- -
-
- - - -
- -

Why gRPC?

- gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services. - - -
- -
- -
- -
- - -
-
Simple service definition
-Define your service using Protocol Buffers, a powerful binary serialization toolset and language -
-
-
- -
-
Start quickly and scale
Install runtime and dev environments with a single line and also scale to millions of RPCs per second with the framework -
-
-
-
- -
- - -
-
Works across languages and platforms
Automatically generate idiomatic client and server stubs for your service in a variety of languages and platforms
-
- -
- -
-
Bi-directional streaming and integrated auth
Bi-directional streaming and fully integrated pluggable authentication with http/2 based transport -
-
- -
- - -
-

Used By

-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- -
- - -
-

Want to Learn More?

-Get started by learning concepts and doing our hello world quickstart in language of your choice.
- -
- - - - - - - - - - - - - diff --git a/public/sitemap.xml b/public/sitemap.xml deleted file mode 100644 index 697ef87..0000000 --- a/public/sitemap.xml +++ /dev/null @@ -1,383 +0,0 @@ - - - - - https://cjyabraham.github.io/ - 2019-03-08T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/ - 2019-03-08T00:00:00+00:00 - 0 - - - - https://cjyabraham.github.io/blog/hello-pancakes/ - 2019-03-08T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/state-of-grpc-web/ - 2019-01-08T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/grpc-dotnet-build/ - 2018-12-18T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/grpc-stacks/ - 2018-12-11T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/grpc-web-ga/ - 2018-10-23T00:00:00+00:00 - - - - https://cjyabraham.github.io/about/ - 2018-09-11T14:11:42+07:00 - - - - https://cjyabraham.github.io/blog/a_short_introduction_to_channelz/ - 2018-09-05T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/grpc_on_http2/ - 2018-08-20T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/grpc-with-json/ - 2018-08-15T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/take-the-grpc-survey/ - 2018-08-14T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/http2_smarter_at_scale/ - 2018-07-13T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/gracefully_clean_up_in_grpc_junit_tests/ - 2018-06-26T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/kotlin-gradle-projects/ - 2018-06-19T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/optimizing-grpc-part-2/ - 2018-04-16T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/optimizing-grpc-part-1/ - 2018-03-06T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/deadlines/ - 2018-02-26T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/2018-01-22-grpc-go-engineering-practices/ - 2018-01-22T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/meetup-kit/ - 2017-09-14T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/2017-08-22-grpc-go-perf-improvements/ - 2017-08-22T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/2017-08-17-community-meeting-update/ - 2017-08-17T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/flatbuffers/ - 2017-08-17T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/loadbalancing/ - 2017-06-15T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/helmgrpc/ - 2017-05-15T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/yygrpc/ - 2017-04-12T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/bazel_rules_protobuf/ - 2016-10-13T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/vscogrpc/ - 2016-09-06T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/vendastagrpc/ - 2016-08-29T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/gablogpost/ - 2016-08-23T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/coreos/ - 2016-05-09T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/installation/ - 2016-04-04T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/pubsub/ - 2016-03-24T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/beta_release/ - 2015-10-26T00:00:00+00:00 - - - - https://cjyabraham.github.io/blog/principles/ - 2015-09-08T00:00:00+00:00 - - - - https://cjyabraham.github.io/docs/reference/go/generated-code/ - - - - https://cjyabraham.github.io/docs/reference/python/generated-code/ - - - - https://cjyabraham.github.io/docs/quickstart/android/ - - - - https://cjyabraham.github.io/docs/tutorials/async/helloasync-cpp/ - - - - https://cjyabraham.github.io/docs/guides/auth/ - - - - https://cjyabraham.github.io/docs/guides/benchmarking/ - - - - https://cjyabraham.github.io/docs/quickstart/csharp/ - - - - https://cjyabraham.github.io/docs/reference/c/client/ - - - - https://cjyabraham.github.io/docs/quickstart/cpp/ - - - - https://cjyabraham.github.io/docs/reference/c/server/ - - - - https://cjyabraham.github.io/categories/ - 0 - - - - https://cjyabraham.github.io/community/ - - - - https://cjyabraham.github.io/contribute/ - - - - https://cjyabraham.github.io/docs/guides/contributing/ - - - - https://cjyabraham.github.io/docs/quickstart/dart/ - - - - https://cjyabraham.github.io/docs/ - - - - https://cjyabraham.github.io/docs/guides/error/ - - - - https://cjyabraham.github.io/faq/ - - - - https://cjyabraham.github.io/docs/quickstart/go/ - - - - https://cjyabraham.github.io/docs/guides/ - - - - https://cjyabraham.github.io/docs/reference/java/client/ - - - - https://cjyabraham.github.io/docs/reference/java/generated-code/ - - - - https://cjyabraham.github.io/docs/quickstart/java/ - - - - https://cjyabraham.github.io/docs/reference/java/server/ - - - - https://cjyabraham.github.io/docs/quickstart/node/ - - - - https://cjyabraham.github.io/docs/tutorials/auth/oauth2-objective-c/ - - - - https://cjyabraham.github.io/docs/quickstart/objective-c/ - - - - https://cjyabraham.github.io/docs/quickstart/php/ - - - - https://cjyabraham.github.io/docs/talks/ - - - - https://cjyabraham.github.io/docs/quickstart/python/ - - - - https://cjyabraham.github.io/docs/quickstart/ - - - - https://cjyabraham.github.io/docs/reference/ - - - - https://cjyabraham.github.io/docs/quickstart/ruby/ - - - - https://cjyabraham.github.io/docs/samples/ - - - - https://cjyabraham.github.io/tags/ - 0 - - - - https://cjyabraham.github.io/docs/tutorials/ - - - - https://cjyabraham.github.io/docs/quickstart/web/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/android/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/csharp/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/c/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/dart/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/go/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/java/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/node/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/objective-c/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/php/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/python/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/ruby/ - - - - https://cjyabraham.github.io/docs/tutorials/basic/web/ - - - - https://cjyabraham.github.io/docs/guides/concepts/ - - - \ No newline at end of file diff --git a/public/tags/index.html b/public/tags/index.html deleted file mode 100644 index 3699427..0000000 --- a/public/tags/index.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - gRPC - - - - - - - - - - - - - - - - - -
-
-
- - - -
-
-
-

Tags

-
- - - -
- -
    - - -
-
- - - - - - - - - - diff --git a/public/tags/index.xml b/public/tags/index.xml deleted file mode 100644 index 67f9d97..0000000 --- a/public/tags/index.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Tags on gRPC - https://cjyabraham.github.io/tags/ - Recent content in Tags on gRPC - Hugo -- gohugo.io - en-us - - - - - - \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index 9c61cab..b79e67f 100755 --- a/static/css/style.css +++ b/static/css/style.css @@ -57,6 +57,10 @@ p img { width: 100%; } +.highlight pre { + padding: 1rem; +} + .btn { margin-top: 2%; diff --git a/static/favicons/android-chrome-192x192.png b/static/favicons/android-chrome-192x192.png index be0b649..122c09a 100755 Binary files a/static/favicons/android-chrome-192x192.png and b/static/favicons/android-chrome-192x192.png differ diff --git a/static/favicons/android-chrome-512x512.png b/static/favicons/android-chrome-512x512.png new file mode 100755 index 0000000..0817408 Binary files /dev/null and b/static/favicons/android-chrome-512x512.png differ diff --git a/static/favicons/apple-touch-icon.png b/static/favicons/apple-touch-icon.png index 7ffa7b5..8d3aeca 100755 Binary files a/static/favicons/apple-touch-icon.png and b/static/favicons/apple-touch-icon.png differ diff --git a/static/favicons/browserconfig.xml b/static/favicons/browserconfig.xml deleted file mode 100755 index 4e40787..0000000 --- a/static/favicons/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #ffffff - - - diff --git a/static/favicons/favicon-16x16.png b/static/favicons/favicon-16x16.png index a50da68..70077bd 100755 Binary files a/static/favicons/favicon-16x16.png and b/static/favicons/favicon-16x16.png differ diff --git a/static/favicons/favicon-32x32.png b/static/favicons/favicon-32x32.png index b4b8ec3..c35182c 100755 Binary files a/static/favicons/favicon-32x32.png and b/static/favicons/favicon-32x32.png differ diff --git a/static/favicons/favicon.ico b/static/favicons/favicon.ico index c9882ae..034ebb3 100755 Binary files a/static/favicons/favicon.ico and b/static/favicons/favicon.ico differ diff --git a/static/favicons/manifest.json b/static/favicons/manifest.json deleted file mode 100755 index 4f3b90a..0000000 --- a/static/favicons/manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "grpc", - "icons": [ - { - "src": "\/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image\/png" - } - ], - "theme_color": "#ffffff", - "display": "standalone" -} diff --git a/static/favicons/mstile-150x150.png b/static/favicons/mstile-150x150.png deleted file mode 100755 index ab7edcf..0000000 Binary files a/static/favicons/mstile-150x150.png and /dev/null differ diff --git a/static/favicons/safari-pinned-tab.svg b/static/favicons/safari-pinned-tab.svg deleted file mode 100755 index b9af8d7..0000000 --- a/static/favicons/safari-pinned-tab.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - -Created by potrace 1.11, written by Peter Selinger 2001-2013 - - - - - diff --git a/static/favicons/site.webmanifest b/static/favicons/site.webmanifest new file mode 100755 index 0000000..45dc8a2 --- /dev/null +++ b/static/favicons/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file