Merge pull request #119 from lucperkins/lperkins/css-framework

Use CSS framework for site
This commit is contained in:
Luc Perkins 2020-03-10 11:50:28 -07:00 committed by GitHub
commit 21072b6f4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
251 changed files with 19501 additions and 2964 deletions

View File

@ -9,7 +9,3 @@ indent_style = tab
[*.{html,js,json,md,sass,yaml}]
indent_style = space
indent_size = 2
[*.py]
indent_style = space
indent_size = 4

View File

@ -1,5 +1,5 @@
HUGO_VERSION = 0.66.0
DOCKER_IMG := klakegg/hugo:$(HUGO_VERSION)
DOCKER_IMG := klakegg/hugo:$(HUGO_VERSION)-ext
SERVE_CMD = server --buildDrafts --buildFuture --disableFastRender --ignoreCache
clean:

View File

@ -1,6 +1,5 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
date: {{ dateFormat "2006-01-02" .Date }}
draft: true
---

278
assets/sass/style.sass Normal file
View File

@ -0,0 +1,278 @@
@charset "utf-8"
{{ $fontAwesomeVersion := site.Params.font_awesome_version }}
{{ $fonts := site.Params.fonts }}
{{ if $fonts }}
{{ $fontSlice := (slice) }}
{{ range $fonts }}
{{ $fontSlice = $fontSlice | append (printf "%s:%s" (replace .name " " "+") (delimit .sizes ",")) }}
{{ end }}
{{ $fontsUrl := printf "https://fonts.googleapis.com/css?family=%s" (delimit $fontSlice "|") }}
@import url("{{ $fontsUrl }}")
{{ end }}
{{ with $fontAwesomeVersion }}
{{ $fontAwesomeUrl := printf "https://use.fontawesome.com/releases/v%s/css/all.css" . }}
@import url("{{ $fontAwesomeUrl }}")
{{ end }}
// Site-specific variables here
$grpc-green: #244c5a
$grpc-blue: #5ac5c5
$twitter-blue: rgb(29, 161, 242)
$reddit-orange: rgba(255, 86, 0, 1)
$gitter-magenta: rgb(237, 25, 101)
// Initial Bulma imports
@import "bulma/sass/utilities/initial-variables"
@import "bulma/sass/utilities/functions"
// Bulma-specific overrides
$primary: $grpc-green
$secondary: $grpc-blue
$secondary-dark: darken($secondary, 15%)
$link: $secondary-dark
$code: $primary
$code-background: $white-bis
$section-padding: 3rem 1.5rem
// Font overrides
{{ if $fonts }}
// Sans-serif font
{{ with (index (where $fonts ".type" "sans_serif") 0).name }}
$family-sans-serif: "{{ . }}", BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif
{{ end }}
// Monospace font
{{ with (index (where $fonts ".type" "monospace") 0).name }}
$family-monospace: "{{ . }}", monospace
{{ end }}
{{ end }}
$font-heading: {{ $.Site.Params.heading_font | default "'Fira Sans', sans-serif" }}
// Final Bulma imports
@import "bulma/sass/utilities/derived-variables"
// Bulma variable overrdides that require derived variables like $dark
$colors: mergeColorMaps(("secondary": ($secondary, $white), "twitter-blue": ($twitter-blue, $white), "reddit-orange": ($reddit-orange, $white), "gitter-magenta": ($gitter-magenta, $white)), $colors)
// Bulma core
@import "bulma/sass/utilities/_all"
@import "bulma/sass/base/_all"
@import "bulma/sass/elements/container"
@import "bulma/sass/grid/columns"
@import "bulma/sass/grid/tiles"
@import "bulma/sass/layout/hero"
@import "bulma/sass/layout/section"
@import "bulma/sass/layout/footer"
// Elements
// @import "bulma/sass/elements/box"
@import "bulma/sass/elements/button"
@import "bulma/sass/elements/content"
@import "bulma/sass/elements/icon"
// @import "bulma/sass/elements/image"
// @import "bulma/sass/elements/notification"
// @import "bulma/sass/elements/progress"
// @import "bulma/sass/elements/table"
// @import "bulma/sass/elements/tag"
@import "bulma/sass/elements/title"
// @import "bulma/sass/elements/other"
// Forms
// @import "bulma/sass/form/shared"
// @import "bulma/sass/form/input-textarea"
// @import "bulma/sass/form/checkbox-radio"
// @import "bulma/sass/form/select"
// @import "bulma/sass/form/file"
// @import "bulma/sass/form/tools"
// Components
// @import "bulma/sass/components/breadcrumb"
@import "bulma/sass/components/card"
// @import "bulma/sass/components/dropdown"
@import "bulma/sass/components/level"
// @import "bulma/sass/components/list"
// @import "bulma/sass/components/media"
@import "bulma/sass/components/menu"
// @import "bulma/sass/components/message"
@import "bulma/sass/components/modal"
@import "bulma/sass/components/navbar"
// @import "bulma/sass/components/pagination"
// @import "bulma/sass/components/panel"
@import "bulma/sass/components/tabs"
.has-background-image
background-image: url("/img/graphic-04.svg")
background-repeat: no-repeat
background-size: cover
=logo($d, $t)
+desktop
width: $d
+touch
width: $t
.is-cncf-logo
+logo(50%, 90%)
+desktop
margin-top: 1.25rem
+touch
margin-top: 0.75rem
.is-hero-logo
+logo(50%, 80%)
+desktop
margin-bottom: 2rem
+touch
margin-bottom: 1rem
.is-footer-logo
+logo(50%, 40%)
.is-feature-icon
+tablet
width: 80%
+mobile
width: 30%
+touch
margin: 0 auto
.is-testimonial-logo
max-height: 5rem
margin-bottom: 1.5rem
.is-page
display: flex
flex-direction: column
min-height: 100vh
.is-main
flex: 1
.is-feature-pane
margin-bottom: 2rem
.has-bottom-padding
padding-bottom: 8rem
.user-logo
margin-bottom: 1.5rem
img
+desktop
max-height: 7rem
+touch
max-height: 5rem
.content
.button
margin: 1rem 0
@for $i from 1 through 6
h#{$i}
&::before
margin-top: 5rem
img
&:hover
cursor: pointer
.highlight
margin-bottom: 1rem
p a
font-weight: $weight-medium
&:hover
color: $secondary
.section
&.has-extra-padding
padding: 6rem 2rem
=sticky
position: sticky
position: -webkit-sticky
.is-sticky
+sticky
top: $navbar-height + 3rem
.is-constrained
max-width: 90ch
=active
color: $secondary-dark
font-weight: 700
.nav
&-section
&-title
color: $dark
&.is-active
+active
&-toc
padding: 0.5rem 0 0.75rem 2.5rem
li a
color: $grey
li + li
margin-top: 0.5rem
ul.nav-section-links
margin: 0 0 2rem 1.25rem
li.nav-section-link
font-size: 1.1rem
&.is-active
+active
& + li.nav-section-link
margin-top: 0.5rem
& + &
margin-top: 1.5rem
.blog-list
ul
margin-bottom: 2rem
li + li
margin-top: .5rem
=admon($color)
.icon
color: $color
.admonition
margin-bottom: 2rem
padding: 1.5rem 2rem
border-radius: .5rem
border: 1.5px solid $secondary
&.is-warning
+admon($warning)
&.is-success
+admon($success)
&.is-note
+admon($info)
&.is-requirement
+admon($grey)
.toc
li
font-size: 1.1rem
line-height: 1.3
& + li
margin-top: 0.75rem

View File

@ -2,13 +2,57 @@ baseURL = "https://grpc.io/"
languageCode = "en-us"
title = "gRPC"
pygmentsCodeFences = true
disableKinds = ["taxonomy", "taxonomyTerm"]
[markup.goldmark.renderer]
unsafe = true
[markup.highlight]
style = "manni"
[params]
grpc_release_tag = "v1.27.2"
grpc_release_tag_no_v = "1.27.2"
grpc_java_release_tag = "v1.27.2"
google_analytics_id = "UA-60127042-1"
font_awesome_version = "5.12.1"
milestones_link = "https://github.com/grpc/grpc/milestones"
description = "A high-performance, open source universal RPC framework"
why = """
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.
"""
[params.social]
twitter = "https://twitter.com/grpcio"
gitter = "https://gitter.im/grpc/grpc"
reddit = "https://www.reddit.com/r/grpc"
[[params.features]]
title = "Simple service definition"
description = "Define your service using Protocol Buffers, a powerful binary serialization toolset and language"
icon = "feature-1.svg"
[[params.features]]
title = "Start quickly and scale"
description = "Install runtime and dev environments with a single line and also scale to millions of RPCs per second with the framework"
icon = "feature-2.svg"
[[params.features]]
title = "Works across languages and platforms"
description = "Automatically generate idiomatic client and server stubs for your service in a variety of languages and platforms"
icon = "feature-3.svg"
[[params.features]]
title = "Bi-directional streaming and integrated auth"
description = "Bi-directional streaming and fully integrated pluggable authentication with HTTP/2-based transport"
icon = "feature-4.svg"
[params.logos]
navbar = "grpc-horizontal-white.png"
hero = "grpc-logo.png"
footer = "grpc-horizontal-white.png"
# Configuration required for auto-generating the Netlify _redirects file
[mediaTypes."text/netlify"]
@ -27,72 +71,138 @@ baseName = "release"
[outputs]
home = ["HTML", "REDIRECTS", "RSS", "RELEASE"]
[[params.fonts]]
name = "Open Sans"
sizes = [300, 400, 600, 700]
type = "sans_serif"
# Site menus
[menu]
[[menu.dropdown]]
[[menu.main]]
name = "About"
url = "/about"
weight = 1
[[menu.main]]
name = "Docs"
url = "/docs"
identifier = "docs"
weight = 2
[[menu.main]]
name = "Guides"
url = "/docs/guides"
identifier = "guides"
weight = 3
[[menu.main]]
name = "Blog"
url = "/blog"
weight = 4
[[menu.main]]
name = "Community"
url = "/community"
weight = 5
[[menu.main]]
name = "Packages"
url = "https://packages.grpc.io"
weight = 6
[[menu.main]]
name = "Overview"
url = "/docs"
weight = 1
parent = "docs"
[[menu.dropdown]]
[[menu.main]]
name = "Quick Start"
url = "/docs/quickstart/"
weight = 2
parent = "docs"
[[menu.dropdown]]
name = "Guides"
url = "/docs/guides/"
weight = 3
[[menu.dropdown]]
[[menu.main]]
name = "Tutorials"
url = "/docs/tutorials/"
weight = 4
weight = 3
parent = "docs"
[[menu.dropdown]]
[[menu.main]]
name = "Reference"
url = "/docs/reference/"
weight = 5
weight = 4
parent = "docs"
[[menu.dropdown]]
[[menu.main]]
name = "Samples"
url = "/docs/samples/"
weight = 6
weight = 5
parent = "docs"
[[menu.dropdown]]
[[menu.main]]
name = "Presentations"
url = "/docs/talks"
weight = 7
url = "/docs/talks/"
weight = 6
parent = "docs"
[[menu.guides]]
[[menu.main]]
name = "FAQ"
url = "/faq"
weight = 7
parent = "docs"
[[menu.main]]
name = "What is gRPC?"
url = "/docs/guides/"
weight = 1
parent = "guides"
[[menu.guides]]
[[menu.main]]
name = "gRPC Concepts"
url = "/docs/guides/concepts/"
weight = 2
parent = "guides"
[[menu.guides]]
[[menu.main]]
name = "Authentication"
url = "/docs/guides/auth/"
weight = 3
parent = "guides"
[[menu.guides]]
[[menu.main]]
name = "Error handling and debugging"
url = "/docs/guides/error/"
weight = 4
parent = "guides"
[[menu.guides]]
[[menu.main]]
name = "Benchmarking"
url = "/docs/guides/benchmarking/"
weight = 5
parent = "guides"
[[menu.guides]]
[[menu.main]]
name = "gRPC Wire Format"
url = "https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md"
weight = 6
parent = "guides"
[markup.goldmark.renderer]
unsafe = true
[[menu.buttons]]
name = "Quick Start"
url = "/docs/quickstart"
weight = 1
[[menu.buttons]]
name = "Docs"
url = "/docs"
weight = 2
[[menu.buttons]]
name = "Concepts"
url = "/docs/guides/concepts"
weight = 3
[[menu.buttons]]
name = "Community"
url = "/community"
weight = 4

View File

@ -1,102 +0,0 @@
---
---
<div class="section2">
<a name="arrow"><h1>Why gRPC?</h1></a>
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.
</div>
<div class="cols" >
<div class="col1">
<div class="colpart1">
<img class="col1image" src="img/grpc-newicon-1.svg" style="padding:2%;display:block">
<div class="coltext1">
<h6>Simple service definition</h6>
Define your service using Protocol Buffers, a powerful binary serialization toolset and language
</div>
</div>
<div class="colpart2">
<img class="col1image" src="img/grpc-newicon-2.svg" style="padding:2%;display:block">
<div class="coltext1">
<h6>Start quickly and scale</h6>Install runtime and dev environments with a single line and also scale to millions of RPCs per second with the framework
</div>
</div>
</div>
<div class="col2">
<div class="colpart1">
<img class="col1image" src="img/grpc-newicon-3.svg" style="padding:2%;display:block">
<div class="coltext1">
<h6>Works across languages and platforms</h6>Automatically generate idiomatic client and server stubs for your service in a variety of languages and platforms</div>
</div>
<div class="colpart2">
<img class="col1image" src="img/grpc-newicon-4.svg" style="padding:2%;display:block">
<div class="coltext1">
<h6>Bi-directional streaming and integrated auth</h6>Bi-directional streaming and fully integrated pluggable authentication with http/2 based transport
</div>
</div>
</div></div>
<div class="section3">
<h1>Used By</h1>
<div class="companybox">
<img src="img/square.png">
</div>
<div class="companybox">
<img src="img/netflix.png">
</div>
<div class="companybox">
<img src="img/coreos.png">
</div>
<div class="companybox">
<img src="img/cockroach-labs.png">
</div>
<div class="companybox">
<img src="img/wisconsin.png">
</div>
<div class="companybox">
<img src="img/carbon.png">
</div>
<div class="companybox">
<img src="img/cisco.png">
</div>
<div class="companybox">
<img src="img/juniper.png">
</div>
<div class="companybox" style="margin-right:0% !important">
<img src="img/pingcap7.png">
</div>
</div>
<div class="section3 cncf-section">
<p>
We are a <a href="https://cncf.io" target="_blank">Cloud Native Computing Foundation</a> incubating project.
</p>
<br />
<img src="/img/cncf-color.png">
</div>
<div class="section4">
<h1 style="color:white">Want to Learn More?</h1>
Get started by learning concepts and doing our hello world quickstart in language of your choice. <br>
<div class="button" style="margin-top:3%">
<a href="docs/guides/concepts/"><button>GET STARTED</button></a>
</div>
</div>

View File

@ -1,5 +1,6 @@
---
title: About gRPC
description: Who is using it, why they're using it, and which platforms support it
---
gRPC is a modern open source high performance RPC framework that can run in any
@ -8,21 +9,19 @@ 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:**
### The main usage scenarios
* Efficiently connecting polyglot services in microservices style architecture
* Connecting mobile devices, browser clients to backend services
* Generating efficient client libraries
**Core Features that make it awesome:**
### Core features that make it awesome
* Idiomatic client libraries in 10 languages
* Highly efficient on wire and with a simple service definition framework
* Bi-directional streaming with http/2 based transport
* Pluggable auth, tracing, load balancing and health checking
<hr>
## Whos using gRPC and why?
Many companies are already using gRPC for connecting multiple services in their
@ -32,122 +31,11 @@ Below are details and quotes from some of our early adopters.
Check out what people are saying below.
<div class="testimonialrow">
<div class="testimonialsection">
<div class="testimonialimage">
<a href="https://www.youtube.com/watch?v=-2sWDr3Z0Wo"><img src="../img/square-icon.png" style="width:45%"/></a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage">
<a href="https://github.com/Netflix/ribbon"><img src="../img/netflix-logo.png" /></a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage">
<a href="https://blog.gopheracademy.com/advent-2015/etcd-distributed-key-value-store-with-grpc-http2/">
<img src="../img/coreos-1.png" style="width:30%"/>
</a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
</div>
<div class="testimonialrow">
<div class="testimonialsection">
<div class="testimonialimage">
<a href="https://github.com/cockroachdb/cockroach"><img src="../img/cockroach-1.png"/></a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage">
<a href="https://github.com/CiscoDevNet/grpc-getting-started"><img src="../img/cisco.svg"/></a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage">
<a href="http://www.carbon3d.com"><img src="../img/carbon3d.svg"/></a>
</div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
</div>
<div class="testimonialrow">
<div class="testimonialsection">
<div class="testimonialimage"><a href="https://www.wisc.edu/"><img src="../img/wisc-mad.jpg"/></a></div>
<div>
<span class="testimonialquote"></span>
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.
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage"><a href="https://github.com/Juniper/open-nti"><img src="../img/juniperlogo.png"/></a></div>
<div>
<span class="testimonialquote"></span>
<p>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.</p>
<p>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.</p>
<p>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.</p>
</div>
</div>
<div class="testimonialsection">
<div class="testimonialimage"><a href="http://www.pingcap.com"><img src="../img/pingcap5.png"/></a></div>
<div>
<span class="testimonialquote"></span>
At PingCAP, we use gRPC in almost every project that involves interactions or communications through network. As has been proven, gRPC has well met our demands in terms of performance and usability. We also provide a production-ready gRPC library for Rust.
</div>
</div>
</div>
<div class="clearfix"></div>
{{< testimonials >}}
## Officially supported platforms
<style>
th:first-child { width: 20%; }
</style>
| Language | Platform | Compiler |
| -------- | -------- | -------- |
| C/C++ | Linux/Mac | GCC 4.9+ <br> Clang 3.4+ |
| C/C++ | Windows 7+ | Visual Studio 2015+ |
| C# | Linux/Mac | .NET Core, Mono 4+ |
| C# | Windows 7+ | .NET Core, .NET 4.5+ |
| Dart | Windows/Linux/Mac | Dart 2.0+ |
| Go | Windows/Linux/Mac | Go 1.6+ |
| Java | Windows/Linux/Mac | JDK 8 recommended. Gingerbread+ for Android |
| Node.js | Windows/Linux/Mac | Node v4+ |
| Objective-C | Mac OS X 10.11+/iOS 7.0+ | Xcode 7.2+ |
| PHP (beta) | Linux/Mac | PHP 5.5+ and PHP 7.0+ |
| Python | Windows/Linux/Mac | Python 2.7 and Python 3.4+ |
| Ruby | Windows/Linux/Mac | Ruby 2.3+ |
{{< supported-platforms >}}
## The story behind gRPC
@ -162,5 +50,5 @@ 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, see [gRPC Motivation and Design
Principles blog](/blog/principles).
For more background on why we created gRPC, see the [gRPC Motivation and Design
Principles](/blog/principles) on the [gRPC blog](/blog).

View File

@ -1,27 +0,0 @@
---
attribution: Mugur Marculescu, gRPC
date: "2015-10-26T00:00:00Z"
published: true
title: gRPC releases Beta, opening door for use in production environments.
url: 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>
<p>
Were also taking a big step forward in improving the installation process. Over the past few weeks weve rolled out gRPC packages to <a href="https://packages.debian.org/jessie-backports/libgrpc0">Debian Stable/Backports</a>. Installation in most cases is now a two line install using the Debian package and available language specific package managers (<a href="https://search.maven.org/#artifactdetails%7Cio.grpc%7Cgrpc-core%7C0.9.0%7Cjar">maven</a>, <a href="https://pypi.python.org/pypi/grpcio">pip</a>, <a href="https://rubygems.org/gems/grpc">gem</a>, <a href="https://packagist.org/packages/grpc/grpc">composer</a>, <a href="https://pecl.php.net/package/gRPC">pecl</a>, <a href="https://www.npmjs.com/package/grpc">npm</a>, <a href="https://www.nuget.org/packages/Grpc/">nuget</a>, <a href="https://cocoapods.org/pods/gRPC">pod</a>). In addition <a href="https://hub.docker.com/r/grpc/">gRPC docker images</a> are now available on Docker Hub.
</p>
<p>
Weve updated the <a href="/docs/">documentation</a> on grpc.io to reflect the latest changes and released additional language-specific <a href="/docs/reference/">reference docs</a>. See whats changed with the Beta release in the release notes on GitHub for <a href="https://github.com/grpc/grpc-java/releases/tag/v0.9.0">Java</a>, <a href="https://godoc.org/google.golang.org/grpc">Go</a> and <a href="https://github.com/grpc/grpc/releases/tag/release-0_11_0">all other</a> languages.
</p>
<p>
In keeping in line with our <a href="/blog/principles">principles</a> 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.
</p>
<p>
Weve been very excited to see the community response to gRPC and the various projects starting to use it (<a href="https://coreos.com/blog/etcd-2.2/">etcd v3 experimental api</a>, <a href="https://github.com/gengo/grpc-gateway">grpc-gateway</a> for RESTful APIs and others).
</p>
<p>
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!
</p>

View File

@ -1,48 +0,0 @@
---
attribution: Originally written by Louis Ryan with help from others at Google.
date: "2015-09-08T00:00:00Z"
published: true
title: gRPC Motivation and Design Principles.
url: 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>
<p>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.</p>
<h2>Principles &amp; Requirements</h2>
<p><strong>Services not Objects, Messages not References</strong> - Promote the microservices design philosophy of coarse-grained message exchange between systems while avoiding the <a href="https://martinfowler.com/articles/distributed-objects-microservices.html">pitfalls of distributed objects</a> and the <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing">fallacies of ignoring the network</a>.</p>
<p><strong>Coverage &amp; Simplicity</strong> - 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 &amp; memory limited devices. </p>
<p><strong>Free &amp; Open</strong> - 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.</p>
<p><strong>Interoperability &amp; Reach</strong> - The wire-protocol must be capable of surviving traversal over common internet infrastructure.</p>
<p><strong>General Purpose &amp; Performant</strong> - 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.</p>
<p><strong>Layered</strong> - Key facets of the stack must be able to evolve independently. A revision to the wire-format should not disrupt application layer bindings.</p>
<p><strong>Payload Agnostic</strong> - 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.</p>
<p><strong>Streaming</strong> - 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.</p>
<p><strong>Blocking &amp; Non-Blocking</strong> - 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.</p>
<p><strong>Cancellation &amp; Timeout</strong> - 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.</p>
<p><strong>Lameducking</strong> - Servers must be allowed to gracefully shut-down by rejecting new requests while continuing to process in-flight ones.</p>
<p><strong>Flow-Control</strong> - Computing power and network capacity are often unbalanced between client &amp; server. Flow control allows for better buffer management as well as providing protection from DOS by an overly active peer.</p>
<p><strong>Pluggable</strong> - 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.</p>
<p><strong>Extensions as APIs</strong> - 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.</p>
<p><strong>Metadata Exchange</strong> - 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.</p>
<p><strong>Standardized Status Codes</strong> - 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.</p>

View File

@ -1,43 +0,0 @@
---
attribution: Originally written by Dale Hopkins with additional content by Lisa Carey
and others at Google.
author: Dale Hopkins
company: Vendasta
company-link: https://vendasta.com
date: "2016-07-25T00:00:00Z"
published: false
thumbnail: ../img/vend-icon.png?raw=true
title: Why we have decided to move our APIs to gRPC
url: blog/vendasta
---
Our guest post today comes from Dale Hopkins, CTO of [Vendasta](https://vendasta.com/). 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 (Python GAE) 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.
<!--more-->
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.
# Three Optimizations to our architecture
* 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. 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.
## Four Benefits from gRPC
* 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), and by providing very flexible create endpoints that easily support bulk ingestion (bi-directional streaming). 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. 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 of our performance issues. However, it does make improvements to our endpoint performance, integration with those endpoints, and even in delivery of SDKs.

View File

@ -1,12 +0,0 @@
---
attribution: Mark Mandel, Sandeep Dinesh
date: "2017-09-14T00:00:00Z"
published: true
title: The gRPC Meetup Kit
url: 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>
<p>The meetup kit includes a 15 minute presentation on the basic concepts of gRPC, with accompanying <a href="https://docs.google.com/presentation/d/1dgI09a-_4dwBMLyqfwchvS6iXtbcISQPLAXL6gSYOcc/edit?usp=sharing">slides</a> and <a href="https://www.youtube.com/watch?v=UVsIfSfS6I4">video</a> for either reference or playback, as well as a <a href="https://codelabs.developers.google.com/codelabs/cloud-grpc/index.html">45 minute codelab</a> that takes you through the basics of gRPC in <a href="https://nodejs.org">Node.js</a> and <a href="https://golang.org/">Go</a>. At the end of the codelab participants will have a solid understanding of the fundamentals of gRPC.</p>
<p>If you are thinking about running a gRPC event, make sure to contact us to receive <a href="https://goo.gl/forms/C3TCtFdobz4ippty2">gRPC stickers</a> and/or organise <a href="https://goo.gl/forms/pvxNwWExr5ApbNst2">office hours over Hangouts with the gRPC team</a>! </p>

3
content/blog/_index.md Normal file
View File

@ -0,0 +1,3 @@
---
title: The gRPC Blog
---

View File

@ -1,10 +1,8 @@
---
title: A short introduction to Channelz
author: Yuxuan Li
author-link: https://github.com/lyuxuan
date: "2018-09-05T00:00:00Z"
published: true
title: A short introduction to Channelz
url: blog/a_short_introduction_to_channelz
date: 2018-09-05
---
Channelz is a tool that provides comprehensive runtime info about connections at

View File

@ -1,13 +1,11 @@
---
title: Building gRPC services with bazel and rules_protobuf
attribution: Originally written by Paul Johnston.
author: Paul Cody Johnston
company: PubRef.org
company-link: https://pubref.org
date: "2016-10-13T00:00:00Z"
published: true
date: 2016-10-13
thumbnail: https://avatars3.githubusercontent.com/u/10408150?v=3&s=200
title: Building gRPC services with bazel and rules_protobuf
url: blog/bazel_rules_protobuf
---
[gRPC](/) makes it easier to build high-performance

View File

@ -0,0 +1,20 @@
---
title: gRPC releases Beta, opening door for use in production environments
attribution: Mugur Marculescu, gRPC
date: 2015-10-26
aliases: ["blog/beta_release"]
---
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.
Were also taking a big step forward in improving the installation process. Over the past few weeks weve rolled out gRPC packages to <a href="https://packages.debian.org/jessie-backports/libgrpc0">Debian Stable/Backports</a>. Installation in most cases is now a two line install using the Debian package and available language specific package managers (<a href="https://search.maven.org/#artifactdetails%7Cio.grpc%7Cgrpc-core%7C0.9.0%7Cjar">maven</a>, <a href="https://pypi.python.org/pypi/grpcio">pip</a>, <a href="https://rubygems.org/gems/grpc">gem</a>, <a href="https://packagist.org/packages/grpc/grpc">composer</a>, <a href="https://pecl.php.net/package/gRPC">pecl</a>, <a href="https://www.npmjs.com/package/grpc">npm</a>, <a href="https://www.nuget.org/packages/Grpc/">nuget</a>, [pod](https://cocoapods.org/pods/gRPC)). In addition [gRPC docker images](https://hub.docker.com/r/grpc) are now available on Docker Hub.
Weve updated the [documentation](/docs) on grpc.io to reflect the latest changes and released additional language-specific [reference docs](/docs/reference). See whats changed with the Beta release in the release notes on GitHub for [Java](https://github.com/grpc/grpc-java/releases/tag/v0.9.0), [Go](https://godoc.org/google.golang.org/grpc), and [all other](https://github.com/grpc/grpc/releases/tag/release-0_11_0) languages.
In keeping in line with our [principles](../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.
Weve been very excited to see the community response to gRPC and the various projects starting to use it ([etcd v3 experimental API](https://coreos.com/blog/etcd-2.2), [grpc-gateway](https://github.com/gengo/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!

View File

@ -1,10 +1,9 @@
---
title: 2017-08-17 Community Meeting Update
author: Jaye Pitzeruse
company: Indeed
company-link: https://www.indeed.com
date: "2017-08-17T00:00:00Z"
published: true
title: 2017-08-17 Community Meeting Update
date: 2017-08-17
---
**Next Community Meeting:** Thursday, August 31, 2017 11am Pacific Time (US and Canada)

View File

@ -1,14 +1,12 @@
---
title: gRPC with REST and Open APIs
attribution: Originally written by Brandon Phillips with additional content by Lisa
Carey and others at Google.
Carey and others at Google
author: Brandon Phillips
company: CoreOS
company-link: https://coreos.com
date: "2016-05-09T00:00:00Z"
published: true
date: 2016-05-09
thumbnail: https://avatars2.githubusercontent.com/u/3730757?v=3&s=200
title: gRPC with REST and Open APIs
url: blog/coreos
---
Our guest post today comes from Brandon Phillips of [CoreOS](https://coreos.com/). CoreOS builds open source projects and products for Linux Containers. Their flagship product for consensus and discovery [etcd](https://coreos.com/etcd/) and their container engine [rkt](https://coreos.com/rkt/) are early adopters of gRPC.

View File

@ -1,14 +1,12 @@
---
title: gRPC and Deadlines
author: Gráinne Sheerin, Google SRE
company: Google
company-link: https://www.google.com
date: "2018-02-26T00:00:00Z"
published: true
title: gRPC and Deadlines
url: blog/deadlines
date: 2018-02-26
---
**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.
**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.
<!--more-->

View File

@ -1,14 +1,13 @@
---
title: gRPC Project is now 1.0 and ready for production deployments
attribution: Originally written by Varun Talwar with additional content by Kailash
Sethuraman and others at Google.
author: Varun Talwar
company: Google
company-link: https://cloud.google.com
date: "2016-08-23T00:00:00Z"
published: true
date: 2016-08-23
thumbnail: ../img/gcp-icon.png?raw=true
title: gRPC Project is now 1.0 and ready for production deployments
url: blog/gablogpost
aliases: ["blog/gablogpost"]
---
Today, the gRPC project has reached a significant milestone with its [1.0 release](https://github.com/grpc/grpc/releases).

View File

@ -1,12 +1,10 @@
---
title: Gracefully clean up in gRPC JUnit tests
author: Dapeng Zhang
author-link: https://github.com/dapengzhang0
company: Google
company-link: https://www.google.com
date: "2018-06-26T00:00:00Z"
published: true
title: Gracefully clean up in gRPC JUnit tests
url: blog/gracefully_clean_up_in_grpc_junit_tests
date: 2018-06-26
---
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.
@ -112,5 +110,5 @@ public class MyTest {
Now with [`GrpcCleanupRule`][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!
[GrpcServerRule]:https://github.com/grpc/grpc-java/blob/v1.1.x/testing/src/main/java/io/grpc/testing/GrpcServerRule.java
[GrpcCleanupRule]:https://github.com/grpc/grpc-java/blob/v1.13.x/testing/src/main/java/io/grpc/testing/GrpcCleanupRule.java
[GrpcServerRule]: https://github.com/grpc/grpc-java/blob/v1.1.x/testing/src/main/java/io/grpc/testing/GrpcServerRule.java
[GrpcCleanupRule]: https://github.com/grpc/grpc-java/blob/v1.13.x/testing/src/main/java/io/grpc/testing/GrpcCleanupRule.java

View File

@ -1,10 +1,8 @@
---
title: "gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build"
author: Kirill 'kkm' Katsnelson
author-link: https://github.com/kkm000
date: "2018-12-18T00:00:00Z"
published: true
title: "gRPC Meets .NET SDK And Visual Studio: Automatic Codegen On Build"
url: blog/grpc-dotnet-build
date: 2018-12-18
---
As part of Microsoft's move towards its cross-platform .NET offering, they have
@ -14,6 +12,8 @@ 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.
<!--more-->
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
@ -22,8 +22,6 @@ 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.
<!--more-->
## A Walkthrough
In this blog post, we'll walk through the simplest and probably the most common

View File

@ -1,12 +1,9 @@
---
title: Announcing out-of-the-box support for gRPC in the Flatbuffers serialization library
author: Wouter van Oortmerssen
company: Google
company-link: https://www.google.com
date: "2017-08-17T00:00:00Z"
published: true
title: Announcing out of the box support for gRPC in the Flatbuffers serialization
library.
url: blog/flatbuffers
date: 2017-08-17
---
The recent release of Flatbuffers [version 1.7](https://github.com/google/flatbuffers/releases) introduced truly zero-copy support for gRPC out of the box.
@ -22,9 +19,11 @@ This is currently, fully supported in the C++ implementation of FlatBuffers, wit
## 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:
```proto

View File

@ -1,10 +1,9 @@
---
title: gRPC-Go Engineering Practices
author: Doug Fawley, gRPC-Go TL
company: Google
company-link: google.com
date: "2018-01-22T00:00:00Z"
published: true
title: 2018-01-19 gRPC-Go Engineering Practices
date: 2018-01-22
---
It's the start of the new year, and almost the end of my first full year on the

View File

@ -1,23 +1,20 @@
---
title: gRPC-Go performance Improvements
author: Mahak Mukhi
company: Google
company-link: google.com
date: "2017-08-22T00:00:00Z"
published: true
title: 2017-08-22 gRPC-Go performance Improvements
date: 2017-08-22
---
<p>
<span style="margin-bottom:5%">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.
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.</style>
</p><br>
This blog summarizes the work we have done so far (in chronological order) to improve performance and lays out our near-future plans.
<!--more-->
### Recently Implemented Optimizations
## Recently Implemented Optimizations
###### Expanding stream window on receiving large messages
### Expanding stream window on receiving large messages
[Code link](https://github.com/grpc/grpc-go/pull/1248)
@ -26,7 +23,7 @@ This is an optimization used by gRPC-C to achieve performance benefits for large
This optimization alone provided a 10x improvement for large messages on high-latency networks.
###### Decoupling application reads from connection flow control
### Decoupling application reads from connection flow control
[Code link](https://github.com/grpc/grpc-go/pull/1265)
@ -45,14 +42,13 @@ 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
### Piggyback window updates
[Code link](https://github.com/grpc/grpc-go/pull/1273)
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
### BDP estimation and dynamic flow control window
[Code link](https://github.com/grpc/grpc-go/pull/1310)
@ -72,13 +68,11 @@ Given that we're always bound by the flow control of TCP which for most cases is
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
### 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
### 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.
@ -86,15 +80,11 @@ In our efforts to get rid of unnecessary flushes we recently combined the header
Another related idea proposed by one of our users @petermattic in [this](https://github.com/grpc/grpc-go/pull/1373) 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
### 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:
### Results
* Benchmark on a real network:
@ -104,18 +94,14 @@ For every data frame read from the wire a new memory allocation takes place. The
* [Code link](https://github.com/grpc/grpc-go/compare/master...MakMukhi:http_greeter)
<table>
<tr><th>Message Size </th><th>GRPC </th><th>HTTP 1.1</th></tr>
<tr><td>1 KB</td><td>~152 ms</td><td>~152 ms</td></tr>
<tr><td>10 KB</td><td>~152 ms</td><td>~152 ms</td></tr>
<tr><td>10 KB</td><td>~152 ms</td><td>~152 ms</td></tr>
<tr><td>1 MB</td><td>~152 ms</td><td>~152 ms</td></tr>
<tr><td>10 MB</td><td>~622 ms</td><td>~630 ms</td></tr>
<tr><td>100 MB</td><td>~5 sec</td><td>~5 sec</td></tr>
</table>
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
* Benchmark on simulated network:
* Server and client were launched on the same machine and different network latencies were simulated.
@ -124,9 +110,9 @@ For every data frame read from the wire a new memory allocation takes place. The
* Following tables show time taken by first 10 RPCs.
* [Code link](https://github.com/grpc/grpc-go/compare/master...MakMukhi:grpc_vs_http)
##### No Latency Network
##### No-latency Network
| GRPC | HTTP 2.0 | HTTP 1.1 |
| gRPC | HTTP 2.0 | HTTP 1.1 |
| --------------|:-------------:|-----------:|
|5.097809ms|16.107461ms|18.298959ms |
|4.46083ms|4.301808ms|7.715456ms
@ -141,7 +127,7 @@ For every data frame read from the wire a new memory allocation takes place. The
##### Network with RTT of 16ms
| GRPC | HTTP 2.0 | HTTP 1.1 |
| gRPC | HTTP 2.0 | HTTP 1.1 |
| --------------|:-------------:|-----------:|
|118.837625ms|84.453913ms|58.858109ms
|36.801006ms|22.476308ms|20.877585ms

View File

@ -1,11 +1,9 @@
---
title: gRPC Load Balancing
author: makdharma
company: Google
company-link: https://www.google.com
date: "2017-06-15T00:00:00Z"
published: true
title: gRPC Load Balancing
url: blog/loadbalancing
date: 2017-06-15
---
This post describes various load balancing scenarios seen when deploying gRPC. If you use [gRPC](/) with multiple backends, this document is for you.

View File

@ -1,10 +1,8 @@
---
title: .NET Core ❤ gRPC
author: Sourabh Shirhatti
author-link: https://twitter.com/sshirhatti
date: "2019-09-23T00:00:00Z"
published: true
title: .NET Core ❤ gRPC
url: blog/grpc-on-dotnetcore
date: 2019-09-23
---
_This is a guest post by [Sourabh Shirhatti](https://twitter.com/sshirhatti), a Program Manager on the .NET team at Microsoft._

View File

@ -1,24 +1,23 @@
---
author: Jean de Klerk
author-link: https://github.com/jadekler
date: "2018-08-20T00:00:00Z"
published: true
title: gRPC on HTTP/2 Engineering a Robust, High Performance Protocol
url: blog/grpc_on_http2
author: Jean de Klerk
author-link: https://github.com/jadekler
date: 2018-08-20
---
In a [previous article](/blog/http2_smarter_at_scale), 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, well look at how gRPC builds on HTTP/2s 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.
<!--more-->
## gRPC Semantics
To begin, lets 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.
<img src="/img/channels_mapping_2.png" title="Channel Mapping" alt="Channel Mapping" style="max-width: 800px">
![Channel mapping](/img/channels_mapping_2.png)
Lets take a look at how gRPC semantics relate to HTTP/2:
<img src="/img/grpc_on_http2_mapping_2.png" title="gRPC on HTTP/2" alt="gRPC on HTTP/2" style="max-width: 800px">
![gRPC on HTTP/2](/img/grpc_on_http2_mapping_2.png)
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.
@ -28,9 +27,9 @@ Channels represent virtual connections to an endpoint, which in reality may be b
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.
<img src="/img/dns_to_load_balancer_mapping_3.png" title="Resolvers and Load Balancers" alt="Resolvers and Load Balancers" style="max-width: 800px">
![Resolvers and Load Balancers](/img/dns_to_load_balancer_mapping_3.png)
<img src="/img/load_balance_round_robins_2.png" alt="Round Robin Load Balancer" style="max-width: 800px">
![Round Robin Load Balancer](/img/load_balance_round_robins_2.png)
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.

View File

@ -1,10 +1,8 @@
---
title: Visualizing gRPC Language Stacks
author: Carl Mastrangelo
author-link: https://carlmastrangelo.com/
date: "2018-12-11T00:00:00Z"
published: true
title: Visualizing gRPC Language Stacks
url: blog/grpc-stacks
date: 2018-12-11
---
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.

View File

@ -1,9 +1,7 @@
---
author: Luc Perkins - CNCF, Stanley Cheung - Google, Kailash Sethuraman - Google
date: "2018-10-23T00:00:00Z"
published: true
title: gRPC-Web is Generally Available
url: blog/grpc-web-ga
author: Luc Perkins - CNCF, Stanley Cheung - Google, Kailash Sethuraman - Google
date: 2018-10-23
---
We are excited to announce the GA release of
@ -35,7 +33,6 @@ From a broader architectural perspective, gRPC-Web enables end-to-end gRPC. The
<img src="/img/grpc-web-arch.png" style="max-width: 947px">
<p style="text-align: center"> Figure 1.
gRPC with gRPC-Web (left) and gRPC with REST (right)</p>

View File

@ -1,12 +1,10 @@
---
title: gRPC + JSON
author: Carl Mastrangelo
author-link: https://carlmastrangelo.com
company: Google
company-link: https://www.google.com
date: "2018-08-15T00:00:00Z"
published: true
title: gRPC + JSON
url: blog/grpc-with-json
date: 2018-08-15
---
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?
@ -227,4 +225,3 @@ Almost **10x** faster than before! We can still take advantage of gRPC's effici
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, Capn 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](https://github.com/carl-mastrangelo/kvstore/tree/04-gson-marshaller) if you would like to see a fully working implementation.

View File

@ -1,10 +1,8 @@
---
title: Dear gRPC
author: April Nassi
author-link: https://www.thisisnotapril.com/
date: "2019-03-08T00:00:00Z"
published: true
title: Dear gRPC
url: blog/hello-pancakes
date: 2019-03-08
---
Dear gRPC,
@ -15,7 +13,7 @@ You're 4 now and that's a big milestone! You're part of so much amazing technolo
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 **G**olden **R**etriever and his name is **P**an**C**akes. 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.
<img src="https://raw.githubusercontent.com/grpc/grpc-community/master/PanCakes/Pancakes_Birthday.png" alt="gRPC Mascot PanCakes" style="max-width: 547px">
![gRPC Mascot PanCakes](https://raw.githubusercontent.com/grpc/grpc-community/master/PanCakes/Pancakes_Birthday.png)
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](https://events.linuxfoundation.org/events/grpconf-2019/) 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](http://www.cci.org/) will be there to greet conference attendees and share how they help their humans live a more independent life.
@ -23,4 +21,4 @@ We are so excited to see what this year holds for you, gRPC!
~ gRPC Maintainers
<img src="https://raw.githubusercontent.com/grpc/grpc-community/master/PanCakes/Pancakes_Birthday_4.png" alt="gRPC Mascot PanCakes" style="max-width: 547px">
![gRPC Mascot PanCakes](https://raw.githubusercontent.com/grpc/grpc-community/master/PanCakes/Pancakes_Birthday_4.png)

View File

@ -1,12 +1,10 @@
---
title: gRPC in Helm
author: Brian Hardock
company: DEIS
company-link: https://deis.com/
date: "2017-05-15T00:00:00Z"
published: true
date: 2017-05-15
thumbnail: https://gabrtv.github.io/deis-dockercon-2014/img/DeisLogo.png
title: gRPC in Helm
url: blog/helmgrpc
---
*Our guest post today comes from Brian Hardock, a software engineer from Deis working on the [Helm](https://helm.sh/) project.*

View File

@ -1,15 +1,14 @@
---
title: HTTP/2 Smarter At Scale
author: Jean de Klerk
author-link: https://github.com/jadekler
company: Google
company-link: https://www.google.com
date: "2018-07-13T00:00:00Z"
published: true
title: HTTP/2 Smarter At Scale
url: blog/http2_smarter_at_scale
date: 2018-07-13
---
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 its beginning to show its age; for the most part, in that the designers werent 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.
<!--more-->
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.1s design in a number of ways, perhaps most significantly in providing a semantic mapping over connections. In this post well explore the concept of streams and how they can be of substantial benefit to software engineers.
@ -20,7 +19,7 @@ Theres significant overhead to creating HTTP connections. You must establish
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 its 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.
<img src="/img/conn_stream_frame_mapping.png" alt="Kotlin Android app example" style="max-width: 800px">
![Kotlin Android app example](/img/conn_stream_frame_mapping.png)
## Streams Provide Concurrency
@ -30,13 +29,13 @@ To illustrate this point, consider the case of some service A sending HTTP/1.1 r
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.
<img src="/img/http2_queue_3.png" alt="Kotlin Android app example" style="max-width: 800px">
![Kotlin Android app example](/img/http2_queue_3.png)
Meanwhile, with HTTP/2, streaming allows messages to be sent concurrently on the same connection. Lets 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 dont 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!
<img src="/img/http2_round_robin.png" alt="Kotlin Android app example" style="max-width: 800px">
![Kotlin Android app example](/img/http2_round_robin.png)
## Flow Control

View File

@ -1,20 +1,19 @@
---
title: gRPC - now with easy installation
attribution: Originally written by Lisa Carey with help from others at Google.
date: "2016-04-04T00:00:00Z"
title: gRPC - now with easy installation.
url: blog/installation
date: 2016-04-04
---
Today we are happy to provide an update that significantly simplifies the getting started experience for gRPC.
* For most languages, **the gRPC runtime can now be installed in a single step via native package managers** such as `npm` for Node.js, `gem` for Ruby and `pip` for Python. Even though our Node, Ruby and Python runtimes are wrapped on gRPC's C core, users now don't need to explicitly pre-install the C core library as a package in most Linux distributions. We autofetch it for you :-).
* **For Java, we have simplified the steps needed to add gRPC support to your build tools** 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.
* You can also use our Dockerfiles to use these updated packages - deploying microservices built on gRPC should now be a very simple experience.
<!--more-->
* For most languages, **the gRPC runtime can now be installed in a single step via native package managers** such as `npm` for Node.js, `gem` for Ruby and `pip` for Python. Even though our Node, Ruby and Python runtimes are wrapped on gRPC's C core, users now don't need to explicitly pre-install the C core library as a package in most Linux distributions. We autofetch it for you :-).
* **For Java, we have simplified the steps needed to add gRPC support to your build tools** 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.
* You can also use our Dockerfiles to use these updated packages - deploying microservices built on gRPC should now be a very simple experience.
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?

View File

@ -1,16 +1,16 @@
---
title: gRPC ❤ Kotlin
author: Spencer Fang
author-link: https://github.com/zpencer
company: Google
company-link: https://www.google.com
date: "2018-06-19T00:00:00Z"
published: true
title: gRPC ❤ Kotlin
url: blog/kotlin-gradle-projects
date: 2018-06-19
---
Did you know that gRPC Java now has out of box support for Kotlin projects built with Gradle? [Kotlin](https://kotlinlang.org/) 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](https://github.com/google/protobuf-gradle-plugin/releases) 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.
<!--more-->
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
@ -20,6 +20,7 @@ The full example can be found [here](https://github.com/grpc/grpc-java/tree/mast
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:
```groovy
apply plugin: 'kotlin'
apply plugin: 'com.google.protobuf'
@ -127,6 +128,6 @@ Just like the non-Android project, run `./gradlew generateProto generateProto` t
Finally, test out the Android app by opening the project in Android Studio and selecting `Run > Run 'app'`.
<img src="/img/kotlin-project-android-app.png" alt="Kotlin Android app example" style="max-width: 404px">
![Kotlin Android app example](/img/kotlin-project-android-app.png)
We are excited about improving the gRPC experience for Kotlin developers. Please add enhancement ideas or bugs to the [protobuf-gradle-plugin issue tracker](https://github.com/google/protobuf-gradle-plugin/issues) or the [grpc-java issue tracker](https://github.com/grpc/grpc-java/issues).

View File

@ -0,0 +1,11 @@
---
title: The gRPC Meetup Kit
date: 2017-09-14
attribution: Mark Mandel, Sandeep Dinesh
---
If you have ever wanted to run an event around [gRPC](/), but didn't know where to start, or weren't sure what content is available - we have released the [gRPC Meetup Kit](https://github.com/grpc-ecosystem/meetup-kit)!
The meetup kit includes a 15 minute presentation on the basic concepts of gRPC, with accompanying [slides](https://docs.google.com/presentation/d/1dgI09a-_4dwBMLyqfwchvS6iXtbcISQPLAXL6gSYOcc/edit?usp=sharing) and [video](https://www.youtube.com/watch?v=UVsIfSfS6I4) for either reference or playback, as well as a [45-minute codelab](https://codelabs.developers.google.com/codelabs/cloud-grpc/index.html) that takes you through the basics of gRPC in [Node.js](https://nodejs.org) and [Go](https://golang.org). 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](https://goo.gl/forms/C3TCtFdobz4ippty2) and/or organise [office hours over Hangouts with the gRPC team](https://goo.gl/forms/pvxNwWExr5ApbNst2)!

View File

@ -1,28 +1,25 @@
---
title: Mobile Benchmarks
attribution: Originally written by David Cao with additional content by Makarand and
others at Google.
author: David Cao
company: Google
company-link: https://cloud.google.com
date: "2016-07-26T00:00:00Z"
published: false
date: 2016-07-26
thumbnail: ../img/gcp-icon.png?raw=true
title: Mobile Benchmarks
url: blog/mobile-benchmarks
---
As gRPC has become a better and faster RPC framework, we've consistently gotten the question, "How _much_ faster is gRPC?" We already have comprehensive server-side benchmarks, but we don't have mobile benchmarks. Benchmarking a client is a bit different than benchmarking a server. We care more about things such as latency and request size and less about things like queries per second (QPS) and number of concurrent threads. Thus we built an Android app in order to quantify these factors and provide solid numbers behind them.
Specifically what we want to benchmark is client side protobuf vs. JSON serialization/deserialization and gRPC vs. a RESTful HTTP JSON service. For the serialization benchmarks, we want to measure the size of messages and speed at which we serialize and deserialize. For the RPC benchmarks, we want to measure the latency of end-to-end requests and packet size.
Protobuf vs. JSON
## Protobuf vs. JSON
In order to benchmark protobuf and JSON, we ran serializations and deserializations over and over on randomly generated protos, which can be seen [here](https://github.com/david-cao/gRPCBenchmarks/tree/master/protolite_app/app/src/main/proto). These protos varied quite a bit in size and complexity, from just a few bytes to over 100kb. JSON equivalents were created and then also benchmarked. For the protobuf messages, we had three main methods of serializing and deserializing: simply using a byte array, `CodedOutputStream`/`CodedInputStream` which is protobuf's own implementation of input and output streams, and Java's `ByteArrayOutputStream` and `ByteArrayInputStream`. For JSON we used `org.json`'s [`JSONObject`](https://developer.android.com/reference/org/json/JSONObject.html). This only had one method to serialize and deserialize, `toString()` and `new JSONObject()`, respectively.
In order to keep benchmarks as accurate as possible, we wrapped the code to be benchmarked in an interface and simply looped it for a set number of iterations. This way we discounted any time spent checking the system time.
``` Java
```java
interface Action {
void execute();
}
@ -39,6 +36,7 @@ for (int i = 0; i < 100; ++i) {
a.execute();
}
```
Before running a benchmark, we ran a warmup in order to clean out any erratic behaviour by the JVM, and then calculated the number of iterations needed to run for a set time (10 seconds in the protobuf vs. JSON case). To do this, we started with 1 iteration, measured the time it took for that run, and compared it to a minimum sample time (2 seconds in our case). If the number of iterations took long enough, we estimated the number of iterations needed to run for 10 seconds by doing some math. Otherwise, we multiplied the number of iterations by 2 and repeated.
```Java
@ -54,22 +52,19 @@ while (elapsed < MIN_SAMPLE_TIME_MS) {
iterations = (int) ((TARGET_TIME_MS / (double) elapsed) * iterations);
```
Results
## Results
Benchmarks were run on protobuf, JSON, and gzipped JSON.
We found that regardless of the serialization/deserialization method used for protobuf, it was consistently about 3x faster for serializing than JSON. For deserialization, JSON is actually a bit faster for small messages (<1kb), around 1.5x, but for larger messages (>15kb) protobuf is 2x faster. For gzipped JSON, protobuf is well over 5x faster in serialization, regardless of size. For deserialization, both are about the same at small messages, but protobuf is about 3x faster for larger messages. Results can be explored in more depth and replicated [here](/github_readme).
gRPC vs. HTTP JSON
We found that regardless of the serialization/deserialization method used for protobuf, it was consistently about 3x faster for serializing than JSON. For deserialization, JSON is actually a bit faster for small messages (<1kb), around 1.5x, but for larger messages (>15kb) protobuf is 2x faster. For gzipped JSON, protobuf is well over 5x faster in serialization, regardless of size. For deserialization, both are about the same at small messages, but protobuf is about 3x faster for larger messages. Results can be explored in more depth and replicated [in the README](https://github.com/david-cao/gRPCBenchmarks).
## gRPC vs. HTTP JSON
To benchmark RPC calls, we want to measure end-to-end latency and bandwidth. To do this, we ping pong with a server for 60 seconds, using the same message each time, and measure the latency and message size. The message consists of some fields for the server to read, and a payload of bytes. We compared gRPC's unary call to a simple RESTful HTTP JSON service. The gRPC benchmark creates a channel, and starts a unary call that repeats when it recieves a response until 60 seconds have passed. The response contains a proto with the same payload sent.
Similarly for the HTTP JSON benchmarks, it sends a POST request to the server with an equivalent JSON object, and the server sends back a JSON object with the same payload.
```Java
```java
// This can be found in AsyncClient.java doUnaryCalls()
// Make stub to send unary call
final BenchmarkServiceStub stub = BenchmarkServiceGrpc.newStub(channel);
@ -109,11 +104,11 @@ stub.unaryCall(request, new StreamObserver<SimpleResponse>() {
}
});
```
Both `HttpUrlConnection` and the [OkHttp library](https://square.github.io/okhttp/) were used.
Only gRPC's unary calls were benchmarked against HTTP, since streaming calls were over 2x faster than the unary calls. Moreover, HTTP has no equivalent of streaming, which is an HTTP/2 specific feature.
## Results
Results
In terms of latency, gRPC is **5x-10x** faster up to the 95th percentile, with averages of around 2 milliseconds for an end-to-end request. For bandwidth, gRPC is about 3x faster for small requests (100-1000 byte payload), and consistently 2x faster for large requests (10kb-100kb payload). To replicate these results or explore in more depth, check out our [repository](/github_readme).
In terms of latency, gRPC is **5x-10x** faster up to the 95th percentile, with averages of around 2 milliseconds for an end-to-end request. For bandwidth, gRPC is about 3x faster for small requests (100-1000 byte payload), and consistently 2x faster for large requests (10kb-100kb payload). To replicate these results or explore in more depth, check out our [repository](https://github.com/david-cao/gRPCBenchmarks).

View File

@ -1,12 +1,10 @@
---
title: So You Want to Optimize gRPC - Part 1
author: Carl Mastrangelo
author-link: https://github.com/carl-mastrangelo
company: Google
company-link: https://www.google.com
date: "2018-03-06T00:00:00Z"
published: true
title: So You Want to Optimize gRPC - Part 1
url: blog/optimizing-grpc-part-1
date: 2018-03-06
---
A common question with gRPC is how to make it fast. The gRPC library offers users access to high
@ -61,26 +59,26 @@ As mentioned above, the client makes random RPCs. For example, here is the code
request:
```java
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;
}
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
@ -101,21 +99,21 @@ On the server side, the request is received by the
[service handler](https://github.com/carl-mastrangelo/kvstore/blob/f422b1b6e7c69f8c07f96ed4ddba64757242352c/src/main/java/io/grpc/examples/KvService.java#L34):
```java
private final Map<ByteBuffer, ByteBuffer> store = new HashMap<>();
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());
@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 `ByteBuffer`s from the request. It acquires the lock
@ -164,21 +162,21 @@ decides](https://github.com/carl-mastrangelo/kvstore/blob/f422b1b6e7c69f8c07f96e
what operation to do:
```java
void doClientWork(AtomicBoolean done) {
Random random = new Random();
KeyValueServiceBlockingStub stub = KeyValueServiceGrpc.newBlockingStub(channel);
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++;
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
@ -192,7 +190,7 @@ Our code can do about 16 queries in a second, so that seems about right. We can
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`](https://github.com/carl-mastrangelo/kvstore/blob/f422b1b6e7c69f8c07f96ed4ddba64757242352c/src/main/java/io/grpc/examples/KvService.java#L88)
method. This implies that the program should be mostly idle while waiting for the RPCs to
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.
@ -228,39 +226,39 @@ is still roughly from top to bottom in the function. Here is the
method revised:
```java
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);
}
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);
@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
@ -323,23 +321,23 @@ permit. To [accomplish](https://github.com/carl-mastrangelo/kvstore/blob/02-fut
this, we will using a `Semaphore`:
```java
private final Semaphore limiter = new Semaphore(100);
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());
/* ... */
}
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.
@ -396,4 +394,3 @@ the very basics of how to approach and think about optimization. Always make su
before and after your changes, and use these measurements to guide your optimizations.
In [Part 2](/blog/optimizing-grpc-part-2), we will continue optimizing the server part of the code.

View File

@ -1,12 +1,10 @@
---
title: So You Want to Optimize gRPC - Part 2
author: Carl Mastrangelo
author-link: https://carlmastrangelo.com/
company: Google
company-link: https://www.google.com
date: "2018-04-16T00:00:00Z"
published: true
title: So You Want to Optimize gRPC - Part 2
url: blog/optimizing-grpc-part-2
date: 2018-04-16
---
How fast is gRPC? Pretty fast if you understand how modern clients and servers are built. In
@ -32,21 +30,21 @@ accidentally corrupt the state of storage. To ensure this, the service uses the
keyword to ensure only one RPC is active at a time:
```java
private final Map<ByteBuffer, ByteBuffer> store = new HashMap<>();
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());
@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
@ -81,21 +79,21 @@ Concurrent maps provide stronger guarantees about the safety of `putIfAbsent`, s
`HashMap` to a `ConcurrentHashMap` and remove `synchronized`:
```java
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());
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
@ -104,21 +102,21 @@ Updating `create` was pretty easy. Doing the same for `retrieve` and `delete` i
However, the `update` method is a little trickier. Let's take a look at what it's doing:
```java
@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();
@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`:
@ -135,21 +133,21 @@ was successful. (`ConcurrentMap` asserts that the operations will not corrupt t
structure, but doesn't say that they will succeed!) We will use a do-while loop:
```java
@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();
}
@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
@ -229,4 +227,3 @@ need to understand what your code is doing. This post shows how to convert a lo
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!

View File

@ -0,0 +1,77 @@
---
title: gRPC Motivation and Design Principles
date: 2015-09-08
attribution: Originally written by Louis Ryan with help from others at Google
---
## 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.
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.</p>
## 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](https://martinfowler.com/articles/distributed-objects-microservices.html) and the [fallacies of ignoring the network](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing).
### 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 and 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 &amp; Reach
The wire protocol must be capable of surviving traversal over common internet infrastructure.
### General Purpose &amp; 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 &amp; 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 &amp; 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 ands 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.

View File

@ -1,9 +1,7 @@
---
attribution: Originally written by Lisa Carey with help from others at Google.
date: "2016-03-24T00:00:00Z"
published: true
title: Google Cloud PubSub - with the power of gRPC!
url: blog/pubsub
attribution: Originally written by Lisa Carey with help from others at Google.
date: 2016-03-24
---
[Google Cloud PubSub](https://cloud.google.com/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](https://cloud.google.com/blog/big-data/2016/03/announcing-grpc-alpha-for-google-cloud-pubsub). Now **users can access PubSub via gRPC** and benefit from all the advantages it brings.

View File

@ -1,10 +1,8 @@
---
title: The state of gRPC in the browser
author: Johan Brandhorst
author-link: https://jbrandhorst.com/
date: "2019-01-08T00:00:00Z"
published: true
title: The state of gRPC in the browser
url: blog/state-of-grpc-web
date: 2019-01-08
---
_This is a guest post by_
@ -18,6 +16,8 @@ Its support for polyglot environments, focus on performance, type safety, and
developer productivity has transformed the way developers design their
architectures.
<!--more-->
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.
@ -27,8 +27,6 @@ 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.
<!--more-->
# Beginnings
In the summer of 2016, both a team at Google and

View File

@ -1,20 +1,20 @@
---
title: Take the gRPC Survey!
author: Kailash Sethuraman
author-link: https://github.com/hsaliak
company: Google
company-link: https://www.google.com
date: "2018-08-14T00:00:00Z"
published: true
title: Take the gRPC Survey!
url: blog/take-the-grpc-survey
date: 2018-08-14
---
## 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](http://bit.ly/gRPC18survey). We invite you to participate and provide input that will help us better plan and prioritize.
<!--more-->
## 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.
@ -23,7 +23,7 @@ The gRPC project is looking for feedback to improve the gRPC experience. To do t
## 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
](http://bit.ly/gRPC18survey)
Survey Short link: [http://bit.ly/gRPC18survey](http://bit.ly/gRPC18survey)

View File

@ -1,14 +1,13 @@
---
title: Why we have decided to move our APIs to gRPC
attribution: Originally written by Dale Hopkins with additional content by Lisa Carey
and others at Google.
author: Dale Hopkins
company: Vendasta
company-link: https://vendasta.com
date: "2016-08-29T00:00:00Z"
published: true
date: 2016-08-29
thumbnail: ../img/vend-icon.png?raw=true
title: Why we have decided to move our APIs to gRPC
url: blog/vendastagrpc
aliases: ["blog/vendastagrpc"]
---
Our guest post today comes from Dale Hopkins, CTO of [Vendasta](https://vendasta.com/).

View File

@ -1,14 +1,13 @@
---
title: gRPC at VSCO
attribution: Thanks to the VSCO engineers that worked on this migration.Steven Tang,
Sam Bobra, Daniel Song, Lucas Kacher, and many others.
author: Robert Sayre and Melinda Lu
company: VSCO
company-link: https://vsco.co
date: "2016-09-06T00:00:00Z"
published: true
date: 2016-09-06
thumbnail: ../img/vsco-logo.png?raw=true
title: gRPC at VSCO
url: blog/vscogrpc
aliases: ["blog/vscogrpc"]
---
Our guest post today comes from Robert Sayre and Melinda Lu of VSCO.

View File

@ -1,12 +1,10 @@
---
title: Migration to Google Cloud PlatformgRPC & grpc-gateway
author: Miguel Mendez
company: Yik Yak
company-link: https://yikyakapp.com
date: "2017-04-12T00:00:00Z"
published: true
date: 2017-04-12
thumbnail: https://cdn-images-1.medium.com/max/1600/0*qYehJ2DvPgFcG_nX.
title: Migration to Google Cloud PlatformgRPC & grpc-gateway
url: blog/yygrpc
---
Our guest post today comes from [Miguel Mendez](https://www.linkedin.com/in/miguel-mendez-008231/) of Yik Yak.
@ -36,18 +34,17 @@ Third, it is great that I can use curl from the command line to hit an API, but
The fourth problem with a REST APIs is that, at least until [Swagger](https://swagger.io/) 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:
```php
// Code omitted…
$yak->hidePin=false;
// Code omitted…
$yak->hidePin=true;
// Code omitted…
$yak->hidePin=0;
// Code omitted…
$yak->hidePin=1;
// 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.
@ -55,51 +52,59 @@ What is the type of the field hidePin? You cannot say for certain. It could be a
Problems can also arise when the clients 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:
```php
// 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…
// 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…
## gRPC can address the issues with REST
If youre not familiar with gRPC, its 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, Ill 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 dont 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 dont modify the generated codeand you should not have tothen 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-gatewaybecause REST will be with us for a while…
Youre 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 doesnt 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](https://medium.com/yik-yak-eng/yik-yak-configuration-and-experiment-system-16a5c15ee77c#.7s11d3kqh) 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.

31
content/contribute.md Normal file
View File

@ -0,0 +1,31 @@
---
title: Contributing to gRPC
---
To contribute to gRPC documentation, please fork the [gRPC repository on GitHub](https://github.com/grpc/grpc.io) and start submitting pull requests.
## Contribute guidelines for gRPC
We welcome contributions to any of our three core repositories:
* [gRPC](https://github.com/grpc/grpc)
* [gRPC Java](https://github.com/grpc/grpc-java)
* [gRPC Go](https://github.com/grpc/grpc-go)
{{< button text="View guidelines" url="https://github.com/grpc/grpc/blob/master/CONTRIBUTING.md" >}}
## Contribution guidelines for the gRPC Ecosystem
The [gRPC Ecosystem](https://github.com/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 out the **Propose new project** form.
{{< button text="View guidelines" url="https://github.com/grpc/grpc-contrib/blob/master/CONTRIBUTING.md" >}}
## 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.
{{< button text="Browse this site's source code" url="https://github.com/grpc/grpc.io" >}}
## 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](/community). Please note that in order to be part of the organization, your GitHub account needs to have [two-factor authentication enabled](https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/).

View File

@ -1,46 +0,0 @@
---
title: Contribute
---
<div class="container markdown">
<div class="row">
To contribute to gRPC documentation, please fork the&nbsp;<a href="https://github.com/grpc/grpc.io">GitHub gRPC repository</a> &nbsp;and start submitting pull requests.
<div id="MainRepoInstructions">
<h2>Contribution guidelines for gRPC</h2>
<p>We welcome contributions to either of our three core repositories. <a href="https://github.com/grpc/grpc">gRPC</a>, <a href="https://github.com/grpc/grpc-java">gRPC Java</a> and <a href="https://github.com/grpc/grpc-go">gRPC Go</a>. </p>
<button class="btn btn-grpc waves-effect waves-light"><a href="https://github.com/grpc/grpc/blob/master/CONTRIBUTING.md">View Guidelines</a></button>
</div>
<div id="EcosystemInstructions">
<h2>Contribution guidelines for gRPC Ecosystem</h2>
<p><a href="https://github.com/grpc-ecosystem/">gRPC Ecosystem</a> 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 <a hre="https://docs.google.com/a/google.com/forms/d/119zb79XRovQYafE9XKjz9sstwynCWcMpoJwHgZJvK74/edit">Propose new project form</a>.</p>
<button class="btn btn-grpc waves-effect waves-light"><a href="https://github.com/grpc/grpc-contrib/blob/master/CONTRIBUTING.md">View Guidelines</a></button>
<div id="generalInstructions">
<h2>Edit our site on github</h2>
<p>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.</p>
<button class="btn btn-grpc waves-effect waves-light"><a href="https://github.com/grpc/grpc.io">Browse this site's source code</a></button>
</div>
<div id="githubOrganization">
<h2>Being a member of the gRPC organization on github</h2>
<p>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 <a href="https://grpc.io/community/">get in touch with us</a>. Please note that in order to be part of the organization, your github account needs to have <a href="https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/">two factor security enabled</a>.</p>
</div>
<p></p>
<p></p>
<p></p>
</div>
</div>
</div>
</div>

View File

@ -1,171 +0,0 @@
---
title: "Documentation"
date: 2018-09-11T15:45:50+07:00
draft: false
---
<div class="docssection2">
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 youre new to gRPC we recommend that you read <a href="guides/"><b>What is
gRPC?</b></a> to find out more about our system and how it works. Or, if you want to see gRPC in action first, visit the <a href="quickstart/">QuickStart</a> for your favourite language.
</div>
<div class="doclangsection">
<h4 style="text-align:center;"> gRPC by Language</h4>
<div class="doccols">
<div class="docscol1">
<h3>C++</h3>
<a href="/docs/quickstart/cpp/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/cpp/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc/cpp/index.html">API Reference</a>
<br>
<h3 style="margin-top:3%;">Go</h3>
<a href="/docs/quickstart/go/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/go/">gRPC Basics Tutorial</a><br>
<a href="https://godoc.org/google.golang.org/grpc">API Reference</a><br>
<a href="/docs/reference/go/generated-code/">Generated Code Reference</a>
<br>
<h3 style="margin-top:3%;">Node.js</h3>
<a href="/docs/quickstart/node/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/node/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc/node/">API Reference</a>
<br>
<h3 style="margin-top:3%;">PHP</h3>
<a href="/docs/quickstart/php/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/php/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc/php/namespace-Grpc.html">API Reference</a>
</div>
<div class="docscol2">
<h3>Java</h3>
<a href="/docs/quickstart/java/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/java/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc-java/javadoc/index.html">API Reference</a><br>
<a href="/docs/reference/java/generated-code/">Generated Code Reference</a>
<br>
<h3 style="margin-top:3%;">Ruby</h3>
<a href="/docs/quickstart/ruby/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/ruby/">gRPC Basics Tutorial</a><br>
<a href="https://www.rubydoc.info/gems/grpc">API Reference</a>
<br>
<h3 style="margin-top:3%;">Android Java</h3>
<a href="/docs/quickstart/android/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/android/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc-java/javadoc/index.html">API Reference</a><br>
<a href="/docs/reference/java/generated-code/">Generated Code Reference</a>
<br>
<h3 style="margin-top:3%;">Dart</h3>
<a href="/docs/quickstart/dart/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/dart/">gRPC Basics Tutorial</a><br>
</div>
<div class="docscol3">
<h3>Python</h3>
<a href="/docs/quickstart/python/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/python/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc/python/">API Reference</a><br>
<a href="/docs/reference/python/generated-code/">Generated Code Reference</a>
<br>
<h3 style="margin-top:3%;">C#</h3>
<a href="/docs/quickstart/csharp/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/csharp/">gRPC Basics Tutorial</a><br>
<a href="https://grpc.io/grpc/csharp/api/Grpc.Core.html">API Reference</a><br>
<br>
<a href="/docs/quickstart/csharp-dotnet/">Quick Start Guide (the "grpc-dotnet" version)</a>
<br>
<h3 style="margin-top:3%;">Objective-C</h3>
<a href="/docs/quickstart/objective-c/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/objective-c/">gRPC Basics Tutorial</a><br>
<a href="http://cocoadocs.org/docsets/gRPC/">API Reference</a>
<br>
<h3 style="margin-top:3%;">Web</h3>
<a href="/docs/quickstart/web/">Quick Start Guide</a><br>
<a href="/docs/tutorials/basic/web/">gRPC Basics Tutorial</a><br>
</div>
</div>
</div>
<div class="docusecasesection">
<h4 style="text-align:center;">gRPC by Use Cases</h4>
<div class="doccols" style="background-color:white;margin-top:0px"">
<div class="docstext">
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.
</div>
<div class="docscol1">
<h3 style="padding-bottom:5%;">Last Mile of Computing</h3>
<p><a href="/docs/tutorials/basic/android/">Mobile: Example RouteGuide Client on Android</a></p>
<p><a href="https://github.com/grpc/grpc-web">Web: Browser Client</a></p>
<br>
</div>
<div class="docscol2" >
<h3 style="padding-bottom:5%;">APIs</h3>
<p>
<a href="https://github.com/GoogleCloudPlatform/cloud-bigtable-client">Google Cloud BigTable Client APIs</a></p>
<p><a href="https://cloud.google.com/blog/big-data/2016/03/announcing-grpc-alpha-for-google-cloud-pubsub">Google Cloud PubSub APIs</a></p>
<p><a href="https://cloud.google.com/speech/reference/rpc/">Google Cloud Speech APIs</a></p>
<br>
</div>
<div class="docscol3">
<h3 style="padding-bottom:5%;">Microservices</h3>
<p><a href="https://github.com/dinowernli/java-grpc-prometheus">Monitoring gRPC services using Prometheus in Java</a></p>
<p><a href="https://github.com/mwitkow/go-grpc-prometheus">Tracing gRPC services using Zipkin in Java</a></p>
<p><a href="https://github.com/grpc/grpc/blob/master/doc/load-balancing.md">Load Balancing in gRPC</a></p>
<br>
</div>
</div>
</div>
<div class="docprojectsection">
<h4 style="text-align:center;">gRPC in Other Projects</h4>
<div class="doccols">
<div class="docstext">
gRPC now has a vibrant community of companies, projects, developers who are extending and building around it. Here are some popular projects.
</div>
<div class="docscol1">
<h3 style="padding-bottom:5%;">Popular Projects</h3>
<a href="https://github.com/grpc-ecosystem/grpc-gateway" style="display:block">gRPC Gateway</a>
<a href="https://github.com/grpc-ecosystem/polyglot" style="display:block">Polyglot: gRPC command line client</a>
<a href="https://github.com/google/flatbuffers/tree/master/grpc" style="display:block">FlatBuffer for gRPC</a>
<a href="https://github.com/go-kit/kit/tree/master/transport/grpc" style="display:block">Go kit with gRPC transport</a>
<a href="https://github.com/etcd-io/etcd" style="display:block">etcd</a>
<a href="https://github.com/cockroachdb/cockroach" style="display:block">cockroachdb</a>
<a href="https://github.com/openzipkin/brave/tree/master/archive/brave-grpc" style="display:block">Zipkin for gRPC</a>
<a href="https://github.com/pingcap/tidb" style="display:block">TiDB</a>
<a href="https://github.com/apache/bookkeeper" style="display:block">Apache BookKeeper</a>
<br>
</div>
</div>
</div>

12
content/docs/_index.md Normal file
View File

@ -0,0 +1,12 @@
---
title: Overview
---
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 youre new to gRPC we recommend that you read [What is gRPC?](guides) to find out more about our system and how it works. Or if you want to see gRPC in action first, visit the [Quick Start](quickstart) for your favourite language.
<!-- generated using the shortcode at layouts/shortcodes/language-block.html -->
{{< language-block >}}
## 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.

14
content/docs/example.md Normal file
View File

@ -0,0 +1,14 @@
---
title: Example
draft: true
---
Example doc!
{{< success >}}
Ea sunt quis cillum elit ipsum et sint nostrud sit sit ad ullamco minim aliqua. Exercitation excepteur ut tempor elit id. Officia eiusmod fugiat tempor ipsum anim incididunt. Irure incididunt esse do ad in magna eiusmod aliqua excepteur sunt.
Cupidatat duis est consequat qui tempor elit. Amet aliquip voluptate Lorem ipsum fugiat non amet elit sunt pariatur reprehenderit tempor excepteur nostrud. Consequat tempor ea occaecat quis fugiat officia culpa tempor cillum do. Irure adipisicing enim ipsum consectetur elit.
Ex Lorem ut consequat est enim aliqua aute incididunt labore aliqua. Consectetur occaecat esse Lorem amet fugiat consectetur commodo ea et aliquip dolore consequat cupidatat ut. Magna nisi labore nostrud proident nulla tempor sit occaecat labore commodo anim voluptate tempor anim.
{{< /success >}}

View File

@ -1,19 +1,16 @@
---
layout: guides
title: Guides
description: Task-oriented walkthroughs of common use cases
weight: 2
---
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
protocol buffers as both its Interface Definition Language (**IDL**) and as its underlying message
interchange format. If youre 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](../quickstart).
<div id="toc" class="toc mobile-toc"></div>
### Overview
## Overview
In gRPC, a client application can directly call a method on a server application
on a different machine as if it were a local object, making it easier for you to
@ -24,13 +21,13 @@ 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](../../img/landing-2.svg)
![Concept Diagram](/img/landing-2.svg)
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][PB docs], Googles
By default, gRPC uses [Protocol Buffers][], Googles
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
@ -89,11 +86,11 @@ code for populating, serializing, and retrieving your message types. You'll
see an example of this below.
To learn more about protocol buffers, including how to install `protoc` with the
gRPC plugin in your chosen language, see the [protocol buffers documentation][PB docs].
gRPC plugin in your chosen language, see the [protocol buffers documentation][protocol buffers].
#### Protocol buffer versions
## Protocol buffer versions
While protocol buffers have been available to open source users for some time,
While [protocol buffers][] have been available to open source users for some time,
most examples from this site use protocol buffers version 3 (proto3), which has
a slightly simplified syntax, some useful new features, and supports more
languages. Proto3 is currently available in Java, C++, Dart, Python,
@ -113,6 +110,5 @@ issues with proto2 clients talking to proto3 servers and vice versa.
[golang/protobuf GitHub repo]: https://github.com/golang/protobuf
[proto3 language guide]: https://developers.google.com/protocol-buffers/docs/proto3
[protocol buffers GitHub repo]: https://github.com/google/protobuf/releases
[PB docs]: https://developers.google.com/protocol-buffers/docs/overview
[protocol buffers]: https://developers.google.com/protocol-buffers/docs/overview
[reference documentation]: https://developers.google.com/protocol-buffers/docs/reference/overview

View File

@ -2,11 +2,9 @@
layout: guides
title: Authentication
description: |
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.
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.
---
<div id="toc" class="toc mobile-toc"></div>
### Overview
gRPC is designed to work with a variety of authentication mechanisms, making it
@ -36,10 +34,9 @@ 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.
<p class="note"> <strong>WARNING</strong>: 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.</p>
{{< 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.
{{< /warning >}}
### Authentication API
@ -539,7 +536,6 @@ var scope = 'https://www.googleapis.com/auth/grpc-testing';
$client = new helloworld\GreeterClient('localhost:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
...
```
##### Authenticate with Google

View File

@ -5,10 +5,6 @@ description: |
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.
---
<div id="toc"></div>
<a name="Overview"></a>
### Overview
gRPC is designed for both high-performance and high-productivity
@ -42,9 +38,6 @@ These workers are controlled by a
that takes as input a scenario description (in JSON format) and an
environment variable specifying the host:port of each worker process.
<a name="Languages under test"></a>
### Languages under test
The following languages have continuous performance testing as both
@ -73,8 +66,6 @@ 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.
<a name="Scenarios under test"></a>
### Scenarios under test
There are several important scenarios under test and displayed in the dashboards
@ -89,8 +80,6 @@ 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.
<a name="Testing infrastructure"></a>
### Testing infrastructure
All performance benchmarks are run as instances in GCE through our

View File

@ -10,8 +10,6 @@ language-specific details, see the Quick Start, tutorial, and reference
documentation for your chosen language(s), where available (complete reference
docs are coming soon).
<div id="toc" class="toc mobile-toc"></div>
### Overview
#### Service definition
@ -170,9 +168,7 @@ 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.
<a name="deadlines"></a>
#### Deadlines/Timeouts
#### Deadlines/Timeouts {#deadlines}
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
@ -199,8 +195,6 @@ 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.
<a name="metadata"></a>
#### Metadata
Metadata is information about a particular RPC call (such as [authentication

View File

@ -3,6 +3,4 @@ layout: guides
title: Contribution Guidelines
---
# Contribution Guidelines
Coming soon!

View File

@ -5,8 +5,6 @@ description: |
This page describes how gRPC deals with errors, including gRPC's built-in error codes. Example code in different languages can be found [here](https://github.com/avinassh/grpc-errors).
---
<div id="toc" class="toc mobile-toc"></div>
### Standard error model
As you'll have seen in our concepts document and examples, when a gRPC call

View File

@ -1,17 +1,14 @@
---
title: Quick Start
layout: quickstart
description: Get started with gRPC
weight: 1
---
<div id="toc" class="toc mobile-toc"></div>
These pages show you how to get up and running as quickly as possible in gRPC,
including installing all the tools youll 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.
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](/docs/guides/concepts/).
For more tutorials and examples, see our [Tutorials](/docs/tutorials).

View File

@ -5,8 +5,6 @@ short: Android
description: This guide gets you started with gRPC in Android Java with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- JDK version 7 or higher
@ -17,9 +15,9 @@ description: This guide gets you started with gRPC in Android Java with a simple
[Android Virtual Device]: https://developer.android.com/studio/run/managing-avds.html
[USB debugging]: https://developer.android.com/studio/command-line/adb.html#Enabling
> **Note**: gRPC Java does not support running a server on an Android device.
> For this quick start, the Android client app will connect to a server running
> on your local (non-Android) computer.
{{< note >}}
gRPC Java does not support running a server on an Android device. For this quick start, the Android client app will connect to a server running on your local (non-Android) computer.
{{< /note >}}
### Download the example

View File

@ -5,8 +5,6 @@ short: C++
description: This guide gets you started with gRPC in C++ with a simple working example.
---
<div id="toc"></div>
### Prerequisites
#### gRPC

View File

@ -5,11 +5,9 @@ short: C# with grpc-dotnet
description: This guide gets you started with gRPC for .NET with a simple working example.
---
<div id="toc"></div>
> **Note**: This is a quick start guide for the "grpc-dotnet" implementation of
> gRPC C#s. See [gRPC C# Quick Start](/docs/quickstart/csharp) for how to start
> with the gRPC C# implementation based on native Core library.
{{< note >}}
This is a quick start guide for the "grpc-dotnet" implementation of gRPC C#s. See [gRPC C# Quick Start](../csharp) for how to start with the gRPC C# implementation based on native Core library.
{{< /note >}}
### General project info
@ -21,4 +19,4 @@ The best way to start is the [gRPC ASP.NET Core Tutorial](https://docs.microsoft
### More Examples
More code examples for grpc-dotnet are at https://github.com/grpc/grpc-dotnet/tree/master/examples
More code examples for grpc-dotnet are at [https://github.com/grpc/grpc-dotnet/tree/master/examples](https://github.com/grpc/grpc-dotnet/tree/master/examples).

View File

@ -5,12 +5,9 @@ short: C#
description: This guide gets you started with gRPC in C# with a simple working example.
---
<div id="toc"></div>
> **Note**: This is a quick start guide for the gRPC C# implementation based on
> Core native library. See [gRPC for .NET Quick
> Start](/docs/quickstart/csharp-dotnet/) for how to start with the
> "grpc-dotnet" implementation.
{{< note >}}
This is a quick start guide for the gRPC C# implementation based on Core native library. See [gRPC for .NET Quick Start](..//csharp-dotnet/) for how to start with the "grpc-dotnet" implementation.
{{< /note >}}
### Prerequisites
@ -44,18 +41,22 @@ dependencies for you (`Grpc`, `Grpc.Tools` and `Google.Protobuf` NuGet packages)
### Build the example
#### Using Visual Studio (or Visual Studio for Mac)
* Open the solution `Greeter.sln` with Visual Studio
* Build the solution
#### Using .NET Core SDK from the command line
From the `examples/csharp/Helloworld` directory:
```sh
> 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](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/csharp/HelloworldLegacyCsproj/README.md) example.*
{{< 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](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/csharp/HelloworldLegacyCsproj/README.md) example.
{{< /note >}}
### Run a gRPC application
@ -63,17 +64,17 @@ From the `examples/csharp/Helloworld` directory:
* Run the server:
```sh
> cd GreeterServer
> dotnet run -f netcoreapp2.1
```
```sh
> cd GreeterServer
> dotnet run -f netcoreapp2.1
```
* From another terminal, run the client:
```sh
> cd GreeterClient
> dotnet run -f netcoreapp2.1
```
```sh
> cd GreeterClient
> dotnet run -f netcoreapp2.1
```
Congratulations! You've just run a client-server application with gRPC.
@ -88,7 +89,7 @@ server and the client "stub" have a `SayHello` RPC method that takes a
server, and that this method is defined like this:
```C#
```proto
// The greeting service definition.
service Greeter {
// Sends a greeting
@ -110,7 +111,7 @@ 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:
```C#
```proto
// The greeting service definition.
service Greeter {
// Sends a greeting
@ -220,14 +221,14 @@ example by running `dotnet build Greeter.sln` or by clicking "Build" in Visual S
Just like we did before, from the `examples/csharp/Helloworld` directory:
1. Run the server:
1. Run the server:
```sh
> cd GreeterServer
> dotnet run -f netcoreapp2.1
```
2. From another terminal, run the client:
2. From another terminal, run the client:
```sh
> cd GreeterClient

View File

@ -5,15 +5,15 @@ short: Dart
description: This guide gets you started with gRPC in Dart with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- Dart SDK version 2.0 or higher.
For installation instructions, see [Install Dart](https://dart.dev/install).
> Note: Dart gRPC supports the Flutter and Server platforms.
{{< note >}}
Dart gRPC supports the Flutter and Server platforms.
{{< /note >}}
#### Protocol Buffers v3

View File

@ -5,8 +5,6 @@ short: Go
description: This guide gets you started with gRPC in Go with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- Go version 1.6 or higher.

View File

@ -5,8 +5,6 @@ short: Java
description: This guide gets you started with gRPC in Java with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- JDK version 7 or higher

View File

@ -5,8 +5,6 @@ short: Node
description: This guide gets you started with gRPC in Node with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- Node version 4.0.0 or higher

View File

@ -5,8 +5,6 @@ short: Objective-C
description: This guide gets you started with gRPC on the iOS platform in Objective-C with a simple working example.
---
<div id="toc"></div>
### Before you begin
#### System requirements

View File

@ -5,8 +5,6 @@ short: PHP
description: This guide gets you started with gRPC in PHP with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- PHP 5.5 or higher, 7.0 or higher
@ -82,8 +80,9 @@ or specific version
sudo pecl install grpc-1.7.0
```
Note: for users on CentOS/RHEL 6, unfortunately this step wont work.
Please follow the instructions below to compile the PECL extension from source.
{{< warning >}}
This step unfortunately wont work on CentOS/RHEL 6. Please follow the instructions below to compile the PECL extension from source.
{{< /warning >}}
##### Install on Windows

View File

@ -5,8 +5,6 @@ short: Python
description: This guide gets you started with gRPC in Python with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- Python 2.7, or Python 3.4 or higher

View File

@ -5,8 +5,6 @@ short: Ruby
description: This guide gets you started with gRPC in Ruby with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- Ruby version 2 or higher

View File

@ -5,8 +5,6 @@ short: Web
description: This guide gets you started with gRPC-Web with a simple working example.
---
<div id="toc"></div>
### Prerequisites
- `docker`

View File

@ -1,24 +0,0 @@
---
bodyclass: docs
headline: 'Language Specific API Reference'
layout: docs
title: Reference
type: markdown
weight: 4
---
<p class="lead">Links to the language specific automatically generated API reference documentation.</p>
<ul>
<li><a target="_blank" href="/grpc/cpp/index.html">C++ API</a></li>
<li><a target="_blank" href="https://pub.dev/documentation/grpc">Dart API</a></li>
<li><a target="_blank" href="/grpc-java/javadoc/index.html">Java API</a></li>
<li><a target="_blank" href="/grpc/python/">Python API</a></li>
<li><a target="_blank" href="http://www.rubydoc.info/gems/grpc">Ruby API</a></li>
<li><a target="_blank" href="/grpc/node/">Node.js API</a></li>
<li><a target="_blank" href="/grpc/csharp/api/Grpc.Core.html">C# API ("gRPC C#" implementation)</a></li>
<li><a target="_blank" href="/grpc/csharp-dotnet/api/Grpc.Core.html">C# API ("grpc-dotnet" implementation)</a></li>
<li><a target="_blank" href="https://godoc.org/google.golang.org/grpc">Go API</a></li>
<li><a target="_blank" href="/grpc/php/namespace-Grpc.html">PHP API</a></li>
<li><a target="_blank" href="/grpc/objc/index.html">Objective-C API</a></li>
<li><a target="_blank" href="/grpc/core/">gRPC Core Library (for wrapped languages)</a></ul></li>
</ul>

View File

@ -0,0 +1,8 @@
---
title: Reference
weight: 4
---
Language-specific, automatically generated API reference documentation is available for the following languages and platforms:
{{< api-links >}}

View File

@ -1,15 +0,0 @@
---
bodyclass: docs
headline: C++ Client Reference
layout: docs
title: C++ Client Reference
---
<p class="lead">Being familiar with these will go a long way.</p>
<p>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.</p>

View File

@ -1,15 +0,0 @@
---
bodyclass: docs
headline: C++ Server Reference
layout: docs
title: C++ Server Reference
---
<p class="lead">Being familiar with these will go a long way.</p>
<p>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.</p>

View File

@ -1,9 +1,6 @@
---
bodyclass: docs
headline: Go Generated Code Reference
layout: docs
title: Go Generated Code Reference
---
# Go Generated Code Reference
This guide describes the code generated with the [grpc plugin](https://godoc.org/github.com/golang/protobuf/protoc-gen-go/grpc) to `protoc-gen-go`
when compiling `.proto` files with `protoc`.

View File

@ -1,15 +0,0 @@
---
bodyclass: docs
layout: docs
title: Java Client Reference
---
<h2 class="page-header">Java Client Reference</h2>
<p class="lead">Being familiar with these will go a long way.</p>
<p>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.</p>

View File

@ -1,9 +1,6 @@
---
bodyclass: docs
title: Java Generated Code Reference
layout: docs
---
# Java Generated Code Reference
## Packages

View File

@ -1,14 +0,0 @@
---
bodyclass: docs
layout: docs
title: Java Server Reference
headline : Java Server Reference
---
<p class="lead">Being familiar with these will go a long way.</p>
<p>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.</p>

View File

@ -1,11 +1,7 @@
---
bodyclass: docs
layout: docs
headline: Python Generated Code Reference
title: Python Generated Code Reference
---
# Python Generated Code Reference
## Introduction
gRPC Python relies on the protocol buffers compiler (`protoc`) to generate
@ -121,7 +117,7 @@ generated:
### Stub
<a name="stub"></a>The generated `Stub` class is used by the gRPC clients. It
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
@ -135,7 +131,7 @@ or
### Servicer
<a name="servicer"></a>For each service, a `Servicer` class is generated. This
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
@ -145,7 +141,7 @@ the generated python code.
### Registration Function
<a name="registration-function"></a>For each service, a function will be
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

View File

@ -14,8 +14,6 @@ from the basic [Greeter example](https://github.com/grpc/grpc/tree/{{< param grp
instructions in
[grpc/examples/cpp/helloworld](https://github.com/grpc/grpc/tree/{{< param grpc_release_tag >}}/examples/cpp/helloworld).
<div id="toc"></div>
### Overview
gRPC uses the
@ -38,30 +36,30 @@ the following to make an asynchronous call:
- Initiate the RPC and create a handle for it. Bind the RPC to a
`CompletionQueue`.
```c
```c
CompletionQueue cq;
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
```
```
- Ask for the reply and final status, with a unique tag
```c
```c
Status status;
rpc->Finish(&reply, &status, (void*)1);
```
```
- Wait for the completion queue to return the next tag. The reply and status are
ready once the tag passed into the corresponding `Finish()` call is returned.
```c
```c
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&#95;async&#95;client.cc](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/cpp/helloworld/greeter_async_client.cc).
@ -74,28 +72,28 @@ asynchronously is:
- Build a server exporting the async service
```c
```c
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();
```
```
- Request one RPC, providing a unique tag
```c
```c
ServerContext context;
HelloRequest request;
ServerAsyncResponseWriter<HelloReply> responder;
service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1);
```
```
- Wait for the completion queue to return the tag. The context, request and
responder are ready once the tag is retrieved.
```c
```c
HelloReply reply;
Status status;
void* got_tag;
@ -105,19 +103,19 @@ asynchronously is:
// set reply and status
responder.Finish(reply, status, (void*)2);
}
```
```
- Wait for the completion queue to return the tag. The RPC is finished when the
tag is back.
```c
```c
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
@ -125,73 +123,74 @@ a `CallData` object to maintain the state of each RPC, and uses the address of
this object as the unique tag for the call.
```c
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();
}
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_);
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());
// 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;
}
// 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:
```c
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();
}
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.
@ -206,11 +205,11 @@ Refer to `ServerBuilder::AddCompletionQueue`'s full docstring for more details.
What this means in our example is that `ServerImpl's` destructor looks like:
```c
~ServerImpl() {
server_->Shutdown();
// Always shutdown the completion queue after the server.
cq_->Shutdown();
}
~ServerImpl() {
server_->Shutdown();
// Always shutdown the completion queue after the server.
cq_->Shutdown();
}
```
You can see our complete server example in

View File

@ -22,11 +22,7 @@ Objective-C](/docs/tutorials/basic/objective-c/) and the
[overview](/docs/), and are familiar with OAuth2 concepts like _access
token_.
<div id="toc"></div>
<a name="setup"></a>
### Example code and setup
### Example code and setup {#setup}
The example code for our tutorial is in
[gprc/examples/objective-c/auth_sample](https://github.com/grpc/grpc/tree/
@ -53,23 +49,22 @@ 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
{{< 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](https://developers.google.com/identity/sign-in/ios/).
{{< /note >}}
As with the other Objective-C examples, you also should have
[Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant
tools to generate the client library code. You can obtain the latter by
following [these setup instructions](https://github.com/grpc/homebrew-grpc).
<a name="try"></a>
### Try it out!
### Try it out! {#try}
To try the sample app, first have Cocoapods generate and install the client library for our .proto
files:
@ -105,9 +100,7 @@ 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](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/objective-c/auth_sample/MakeRPCViewController.m).
<a name="rpc-call"></a>
### Create a call with access token
### Create a call with access token {#rpc-call}
To make an authenticated call, first you need to initialize a `GRPCCallOptions` object and configure
it with the access token.
@ -151,9 +144,8 @@ You can then start the RPC represented by this object at any later time like thi
[rpc start];
```
<a name="authorization-protocol">
### An alternative way to provide access token {#authorization-protocol}
### An alternative way to provide access token
Rather than setting `oauth2AccessToken` option in `GRPCCallOptions` before the RPC object is
created, an alternative approach allows users providing access token at call start time.

View File

@ -16,8 +16,6 @@ By walking through this example you'll learn how to:
It assumes that you have read the [Overview](/docs/) and are familiar with [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview).
This guide also does not cover anything on the server side. You can check the [Java guide](/docs/tutorials/basic/java/) for more information.
<div id="toc"></div>
### 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.

View File

@ -23,8 +23,6 @@ guide](https://developers.google.com/protocol-buffers/docs/proto3) and [C++
generated code
guide](https://developers.google.com/protocol-buffers/docs/reference/cpp-generated).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -193,9 +191,7 @@ These contain:
defined in the `RouteGuide` service.
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -361,9 +357,7 @@ As you can see, we build and start our server using a `ServerBuilder`. To do thi
6. Call `Wait()` on the server to do a blocking wait until process is killed or
`Shutdown()` is called.
<a name="client"></a>
### Creating the client
### Creating the client {#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
@ -380,7 +374,10 @@ address and port we want to connect to - in our case we'll use no SSL:
```cpp
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`
{{< note >}}
In order to set additional options for the *channel*, use the `grpc::CreateCustomChannel()` api with any special channel arguments - `grpc::ChannelArguments`.
{{< /note >}}
Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto.

View File

@ -20,8 +20,6 @@ language: you can find out more in the
[proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and
[C# generated code reference](https://developers.google.com/protocol-buffers/docs/reference/csharp-generated).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -170,10 +168,7 @@ under the `RouteGuide/obj/Debug/TARGET_FRAMEWORK` directory:
- a class `RouteGuide.RouteGuideClient` that can be used to access remote
RouteGuide instances
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -353,9 +348,7 @@ do this, we:
This is done by adding `ServerPort` to the `Ports` collection.
1. Call `Start` on the server instance to start an RPC server for our service.
<a name="client"></a>
### Creating the client
### Creating the client {#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

View File

@ -20,8 +20,6 @@ language: you can find out more in the
[proto3 language
guide](https://developers.google.com/protocol-buffers/docs/proto3).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -170,10 +168,7 @@ This contains:
- An interface type for servers to implement, also with the methods defined in
the `RouteGuide` service.
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -380,9 +375,7 @@ To build and start a server, we:
in the address and port to listen on. The server will continue to serve requests
asynchronously until `shutdown()` is called on it.
<a name="client"></a>
### Creating the client
### Creating the client {#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

View File

@ -22,8 +22,6 @@ guide](https://developers.google.com/protocol-buffers/docs/proto3) and the [Go
generated code
guide](https://developers.google.com/protocol-buffers/docs/reference/go-generated).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -170,10 +168,7 @@ This contains:
- An interface type for servers to implement, also with the methods defined in
the `RouteGuide` service.
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -392,9 +387,7 @@ To build and start a server, we:
4. Call `Serve()` on the server with our port details to do a blocking wait
until the process is killed or `Stop()` is called.
<a name="client"></a>
### Creating the client
### Creating the client {#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

View File

@ -23,8 +23,6 @@ guide](https://developers.google.com/protocol-buffers/docs/proto3) and [Java
generated code
guide](https://developers.google.com/protocol-buffers/docs/reference/java-generated).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -179,9 +177,7 @@ The following classes are generated from our service definition:
`RouteGuide` service.
- *stub* classes that clients can use to talk to a `RouteGuide` server.
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -434,9 +430,7 @@ To do this, we:
1. Call `build()` and `start()` on the builder to create and start an RPC server
for our service.
<a name="client"></a>
## Creating the client
## Creating the client {#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

View File

@ -20,8 +20,6 @@ that the example in this tutorial uses the
buffers language. You can find out more in the
[proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -191,9 +189,7 @@ Once you've done this, the stub constructor is in the `routeguide` namespace
used to create a server) is a property of the stub
(`protoDescriptor.routeguide.RouteGuide.service`);
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -368,9 +364,7 @@ As you can see, we build and start our server with the following steps:
using the instance's `bind()` method.
1. Call `start()` on the instance to start the RPC server.
<a name="client"></a>
### Creating the client
### Creating the client {#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

View File

@ -22,11 +22,7 @@ guide](https://developers.google.com/protocol-buffers/docs/proto3) and the
[Objective-C generated code
guide](https://developers.google.com/protocol-buffers/docs/reference/objective-c-generated).
<div id="toc"></div>
<a name="why-grpc"></a>
### Why use gRPC?
### Why use gRPC? {#why-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
@ -44,10 +40,7 @@ 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.
<a name="setup"></a>
### Example code and setup
### Example code and setup {#setup}
The example code for our tutorial is in
[grpc/grpc/examples/objective-c/route_guide](https://github.com/grpc/grpc/tree/{{< param grpc_release_tag >}}/examples/objective-c/route_guide).
@ -76,10 +69,7 @@ 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](https://github.com/grpc/homebrew-grpc).
<a name="try"></a>
## Try it out!
## Try it out! {#try}
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:
@ -108,10 +98,7 @@ 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.
<a name="proto"></a>
### Defining the service
### Defining the service {#proto}
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
@ -200,9 +187,7 @@ You can specify a prefix to be used for your generated classes by adding the
option objc_class_prefix = "RTG";
```
<a name="protoc"></a>
### Generating client code
### Generating client code {#protoc}
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
@ -246,17 +231,17 @@ 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.
<a name="client"></a>
### Creating the client application
### Creating the client application {#client}
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](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/objective-c/route_guide/ViewControllers.m).
(Note: In your apps, for maintainability and readability reasons, you shouldn't
{{< 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).
{{< /note >}}
#### Constructing a service object

View File

@ -22,11 +22,7 @@ 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](/docs/tutorials/basic/node/).
<div id="toc"></div>
<a name="why-grpc"></a>
### Why use gRPC?
### Why use gRPC? {#why-grpcc}
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
@ -36,10 +32,7 @@ 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.
<a name="setup"></a>
### Example code and setup
### Example code and setup {#setup}
The example code for our tutorial is in
[grpc/grpc/examples/php/route_guide](https://github.com/grpc/grpc/tree/{{< param grpc_release_tag >}}/examples/php/route_guide).
@ -73,10 +66,7 @@ interface code (and a server in another language, for testing). You can obtain
the latter by following [these setup
instructions](/docs/tutorials/basic/node/).
<a name="try"></a>
### Try it out!
### Try it out! {#try}
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:
@ -98,10 +88,7 @@ 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.
<a name="proto"></a>
### Defining the service
### Defining the service {#proto}
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
@ -183,10 +170,7 @@ message Point {
}
```
<a name="protoc"></a>
### Generating client code
### Generating client code {#protoc}
The PHP client stub implementation of the proto files can be generated by the
gRPC PHP Protoc Plugin. To compile the plugin:
@ -234,10 +218,7 @@ The file contains:
- A class called `Routeguide\RouteGuideClient` that lets clients call the methods
defined in the `RouteGuide` service.
<a name="client"></a>
### Creating the client
### Creating the client {#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

View File

@ -21,8 +21,6 @@ guide](https://developers.google.com/protocol-buffers/docs/proto3) and [Python
generated code
guide](https://developers.google.com/protocol-buffers/docs/reference/python-generated).
<div id="toc"></div>
### Why use gRPC?
This example is a simple route mapping application that lets clients get
@ -175,11 +173,11 @@ than creates a new one. The generated code files are called
- `add_RouteGuideServicer_to_server`, which adds a RouteGuideServicer to
a `grpc.Server`
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.
{{< 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.
{{< /note >}}
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -313,9 +311,7 @@ def serve():
Because `start()` does not block you may need to sleep-loop if there is nothing
else for your code to do while serving.
<a name="client"></a>
### Creating the client
### Creating the client {#client}
You can see the complete example client code in
[examples/python/route_guide/route_guide_client.py](https://github.com/grpc/grpc/blob/{{< param grpc_release_tag >}}/examples/python/route_guide/route_guide_client.py).

View File

@ -20,8 +20,6 @@ buffers language: you can find out more in
the [proto3 language
guide](https://developers.google.com/protocol-buffers/docs/proto3).
<div id="toc"></div>
### Why use gRPC?
Our example is a simple route mapping application that lets clients get
@ -171,10 +169,7 @@ Running this command regenerates the following files in the lib directory:
implementations
- a class `Stub` that can be used to access remote RouteGuide instances
<a name="server"></a>
### Creating the server
### Creating the server {#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
@ -288,9 +283,7 @@ this, we:
1. Call `run` on the`GRPC::RpcServer` to create and start an RPC server for our
service.
<a name="client"></a>
### Creating the client
### Creating the client {#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
@ -394,7 +387,9 @@ Run the server:
$ bundle exec route_guide/route_guide_server.rb ../python/route_guide/route_guide_db.json
```
> Note: The `route_guide_db.json` file is actually language-agnostic, it happens to be located in the `python` folder.
{{< note >}}
The `route_guide_db.json` file is actually language-agnostic, it happens to be located in the `python` folder.
{{< /note >}}
From a different terminal, run the client:

View File

@ -17,11 +17,7 @@ By walking through this example you'll learn how to:
It assumes a passing familiarity with [protocol
buffers](https://developers.google.com/protocol-buffers/docs/overview).
<div id="toc"></div>
<a name="why-grpc"></a>
### Why use gRPC and gRPC-Web?
### Why use gRPC and gRPC-Web? {#why-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
@ -32,9 +28,7 @@ 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.
<a name="setup"></a>
### Define the Service
### Define the Service {#setup}
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

24
data/apis.yaml Normal file
View File

@ -0,0 +1,24 @@
- language: C++
url: /grpc/cpp
- language: Dart
url: https://pub.dev/documentation/grpc
- language: Java
url: /grpc-java/javadoc
- language: Python
url: /grpc/python
- language: Ruby
url: https://www.rubydoc.info/gems/grpc
- language: Node.js
url: /grpc/node
- language: C# API ("gRPC C#" implementation)
url: /grpc/csharp/api/Grpc.Core
- language: C# API ("grpc-dotnet" implementation)
url: /grpc/csharp-dotnet/api/Grpc.Core
- language: Go
url: https://godoc.org/google.golang.org/grpc
- language: Objective-C
url: /grpc/objc
- language: PHP
url: /grpc/php/namespace-Grpc
- language: gRPC Core Library (for wrapped languages)
url: /grpc/core

0
data/languages.yaml Normal file
View File

36
data/platforms.yaml Normal file
View File

@ -0,0 +1,36 @@
- language: "C/C++"
platforms: ["Linux", "Mac"]
compilers: ["GCC 4.9+", "Clang 3.4+"]
- language: "C/C++"
platforms: ["Windows 7+"]
compilers: ["Visual Studio 2015+"]
- language: "C#"
platforms: ["Linux", "Mac"]
compilers: [".NET Core", "Mono 4+"]
- language: "C#"
platforms: ["Windows 7+"]
compilers: [".NET Core", "NET 4.5+"]
- language: "Dart"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["Dart 2.0+"]
- language: "Go"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["Go 1.6+"]
- language: "Java"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["JDK 8 recommended (Gingerbread+ for Android)"]
- language: "Node.js"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["Node v4+"]
- language: "Objective-C"
platforms: ["Mac OS X 10.11+", "iOS 7.0+"]
compilers: ["Xcode 7.2+"]
- language: "PHP (beta)"
platforms: ["Linux", "Mac"]
compilers: ["PHP 5.5+", "PHP 7.0+"]
- language: "Python"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["Python 2.7", "Python 3.4+"]
- language: "Ruby"
platforms: ["Windows", "Linux", "Mac"]
compilers: ["Ruby 2.3+"]

44
data/testimonials.yaml Normal file
View File

@ -0,0 +1,44 @@
- name: Square
link: https://www.youtube.com/watch?v=-2sWDr3Z0Wo
image: square-icon.png
quote: |
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.
- name: Netflix
link: https://github.com/Netflix/ribbon
image: netflix-logo.png
quote: |
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.
- name: CoreOS
link: https://blog.gopheracademy.com/advent-2015/etcd-distributed-key-value-store-with-grpc-http2
image: coreos-1.png
quote: |
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.
- name: Cockroach Labs
link: https://github.com/cockroachdb/cockroach
image: cockroach-1.png
quote: |
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.
- name: Cisco
link: https://github.com/CiscoDevNet/grpc-getting-started
image: cisco.svg
quote: |
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.
- name: Carbon3D
link: https://www.carbon3d.com
image: carbon3d.svg
quote: |
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.
- name: University of Wisconsin
link: https://www.wisc.edu
image: wisc-mad.jpg
quote: |
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.
- name: Juniper Networks
link: https://github.com/Juniper/open-nti
image: juniperlogo.png
quote: |
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.

58
layouts/404.html Normal file
View File

@ -0,0 +1,58 @@
{{ define "main" }}
<section class="hero is-medium has-background-image">
<div class="hero-body">
<div class="container has-text-centered">
<p class="title is-size-1 is-size-2-mobile has-text-weight-bold is-spaced">
<span class="has-text-white">
404
</span>
<span class="has-text-secondary">
!
</span>
</p>
<p class="subtitle is-size-3 is-size-4-mobile has-text-grey-lighter has-text-weight-medium">
Page not found
</p>
</div>
</div>
</section>
<section class="section">
<div class="container has-text-centered">
<div class="content has-bottom-padding is-medium">
<p>
Sorry, but that link wasn't found. Perhaps you were looking for one of the following:
</p>
<a class="is-size-4 is-size-5-mobile" href="/">
Main page
</a>
<br />
<a class="is-size-4 is-size-5-mobile" href="/docs">
Documentation
</a>
<br />
<a class="is-size-4 is-size-5-mobile" href="/blog">
Blog
</a>
<br />
<a class="is-size-4 is-size-5-mobile" href="/community">
Community
</a>
<br />
<a class="is-size-4 is-size-5-mobile" href="/faq">
FAQ
</a>
</div>
</div>
</section>
{{ end }}

View File

@ -0,0 +1,16 @@
{{ $src := .Destination | safeURL }}
{{ $id := index (last 1 (split .Destination "/")) 0 | replaceRE ".png" "" }}
<figure x-data="{ open: false }">
<img src="{{ $src }}"{{ with .Text }} alt="{{ . }}"{{ end }} id="{{ $id }}" @click="open = true">
<div class="modal" id="modal-{{ $id }}" :class="{ 'is-active': open }">
<div class="modal-background"></div>
<div class="modal-content">
<p class="image">
<img src="{{ $src }}"{{ with .Text }} alt="{{ . }}"{{ end }}>
</p>
</div>
<button class="modal-close is-large" aria-label="close" @click="open = false"></button>
</div>
</figure>

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