Skip to content

Commit

Permalink
examples: Added README files for all missing Examples (grpc#11676)
Browse files Browse the repository at this point in the history
  • Loading branch information
vinodhabib authored Jan 28, 2025
1 parent 87aa6de commit 9e86299
Show file tree
Hide file tree
Showing 22 changed files with 436 additions and 104 deletions.
126 changes: 22 additions & 104 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,114 +27,32 @@ before trying out the examples.

- [Json serialization](src/main/java/io/grpc/examples/advanced)

- <details>
<summary>Hedging</summary>

The [hedging example](src/main/java/io/grpc/examples/hedging) demonstrates that enabling hedging
can reduce tail latency. (Users should note that enabling hedging may introduce other overhead;
and in some scenarios, such as when some server resource gets exhausted for a period of time and
almost every RPC during that time has high latency or fails, hedging may make things worse.
Setting a throttle in the service config is recommended to protect the server from too many
inappropriate retry or hedging requests.)

The server and the client in the example are basically the same as those in the
[hello world](src/main/java/io/grpc/examples/helloworld) example, except that the server mimics a
long tail of latency, and the client sends 2000 requests and can turn on and off hedging.

To mimic the latency, the server randomly delays the RPC handling by 2 seconds at 10% chance, 5
seconds at 5% chance, and 10 seconds at 1% chance.

When running the client enabling the following hedging policy

```json
"hedgingPolicy": {
"maxAttempts": 3,
"hedgingDelay": "1s"
}
```
Then the latency summary in the client log is like the following

```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging enabled]
========================
50% latency: 0ms
90% latency: 6ms
95% latency: 1,003ms
99% latency: 2,002ms
99.9% latency: 2,011ms
Max latency: 5,272ms
========================
```

See [the section below](#to-build-the-examples) for how to build and run the example. The
executables for the server and the client are `hedging-hello-world-server` and
`hedging-hello-world-client`.

To disable hedging, set environment variable `DISABLE_HEDGING_IN_HEDGING_EXAMPLE=true` before
running the client. That produces a latency summary in the client log like the following

```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging disabled]
========================
50% latency: 0ms
90% latency: 2,002ms
95% latency: 5,002ms
99% latency: 10,004ms
99.9% latency: 10,007ms
Max latency: 10,007ms
========================
```

</details>

- <details>
<summary>Retrying</summary>

The [retrying example](src/main/java/io/grpc/examples/retrying) provides a HelloWorld gRPC client &
server which demos the effect of client retry policy configured on the [ManagedChannel](
../api/src/main/java/io/grpc/ManagedChannel.java) via [gRPC ServiceConfig](
https://github.com/grpc/grpc/blob/master/doc/service_config.md). Retry policy implementation &
configuration details are outlined in the [proposal](https://github.com/grpc/proposal/blob/master/A6-client-retries.md).

This retrying example is very similar to the [hedging example](src/main/java/io/grpc/examples/hedging) in its setup.
The [RetryingHelloWorldServer](src/main/java/io/grpc/examples/retrying/RetryingHelloWorldServer.java) responds with
a status UNAVAILABLE error response to a specified percentage of requests to simulate server resource exhaustion and
general flakiness. The [RetryingHelloWorldClient](src/main/java/io/grpc/examples/retrying/RetryingHelloWorldClient.java) makes
a number of sequential requests to the server, several of which will be retried depending on the configured policy in
[retrying_service_config.json](src/main/resources/io/grpc/examples/retrying/retrying_service_config.json). Although
the requests are blocking unary calls for simplicity, these could easily be changed to future unary calls in order to
test the result of request concurrency with retry policy enabled.

One can experiment with the [RetryingHelloWorldServer](src/main/java/io/grpc/examples/retrying/RetryingHelloWorldServer.java)
failure conditions to simulate server throttling, as well as alter policy values in the [retrying_service_config.json](
src/main/resources/io/grpc/examples/retrying/retrying_service_config.json) to see their effects. To disable retrying
entirely, set environment variable `DISABLE_RETRYING_IN_RETRYING_EXAMPLE=true` before running the client.
Disabling the retry policy should produce many more failed gRPC calls as seen in the output log.

See [the section below](#to-build-the-examples) for how to build and run the example. The
executables for the server and the client are `retrying-hello-world-server` and
`retrying-hello-world-client`.

</details>

- <details>
<summary>Health Service</summary>

The [health service example](src/main/java/io/grpc/examples/healthservice)
provides a HelloWorld gRPC server that doesn't like short names along with a
health service. It also provides a client application which makes HelloWorld
calls and checks the health status.

The client application also shows how the round robin load balancer can
utilize the health status to avoid making calls to a service that is
not actively serving.
</details>
- [Hedging example](src/main/java/io/grpc/examples/hedging)

- [Retrying example](src/main/java/io/grpc/examples/retrying)

- [Health Service example](src/main/java/io/grpc/examples/healthservice)

- [Keep Alive](src/main/java/io/grpc/examples/keepalive)

- [Cancellation](src/main/java/io/grpc/examples/cancellation)

- [Custom Load Balance](src/main/java/io/grpc/examples/customloadbalance)

- [Deadline](src/main/java/io/grpc/examples/deadline)

- [Error Details](src/main/java/io/grpc/examples/errordetails)

- [GRPC Proxy](src/main/java/io/grpc/examples/grpcproxy)

- [Load Balance](src/main/java/io/grpc/examples/loadbalance)

- [Multiplex](src/main/java/io/grpc/examples/multiplex)

- [Name Resolve](src/main/java/io/grpc/examples/nameresolve)

- [Pre-Serialized Messages](src/main/java/io/grpc/examples/preserialized)

### <a name="to-build-the-examples"></a> To build the examples

1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions examples/src/main/java/io/grpc/examples/advanced/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
gRPC JSON Serialization Example
=====================

gRPC is a modern high-performance framework for building Remote Procedure Call (RPC) systems.
It commonly uses Protocol Buffers (Protobuf) as its serialization format, which is compact and efficient.
However, gRPC can also support JSON serialization when needed, typically for interoperability with
systems or clients that do not use Protobuf.
This is an advanced example of how to swap out the serialization logic, Normal users do not need to do this.
This code is not intended to be a production-ready implementation, since JSON encoding is slow.
Additionally, JSON serialization as implemented may be not resilient to malicious input.

This advanced example uses Marshaller for JSON which marshals in the Protobuf 3 format described here
https://developers.google.com/protocol-buffers/docs/proto3#json

If you are considering implementing your own serialization logic, contact the grpc team at
https://groups.google.com/forum/#!forum/grpc-io
18 changes: 18 additions & 0 deletions examples/src/main/java/io/grpc/examples/cancellation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
gRPC Cancellation Example
=====================

When a gRPC client is no longer interested in the result of an RPC call,
it may cancel to signal this discontinuation of interest to the server.

Any abort of an ongoing RPC is considered "cancellation" of that RPC.
The common causes of cancellation are the client explicitly cancelling, the deadline expires, and I/O failures.
The service is not informed the reason for the cancellation.

There are two APIs for services to be notified of RPC cancellation: io.grpc.Context and ServerCallStreamObserver

Context listeners are called on a different thread, so need to be thread-safe.
The ServerCallStreamObserver cancellation callback is called like other StreamObserver callbacks,
so the application may not need thread-safe handling.
Both APIs have thread-safe isCancelled() polling methods.

Refer the gRPC documentation for details on Cancellation of RPCs https://grpc.io/docs/guides/cancellation/
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
gRPC Custom Load Balance Example
=====================

One of the key features of gRPC is load balancing, which allows requests from clients to be distributed across multiple servers.
This helps prevent any one server from becoming overloaded and allows the system to scale up by adding more servers.

A gRPC load balancing policy is given a list of server IP addresses by the name resolver.
The policy is responsible for maintaining connections (subchannels) to the servers and picking a connection to use when an RPC is sent.

This example gives the details about how we can implement our own custom load balance policy, If the built-in policies does not meet your requirements
and follow below steps for the same.

- Register your implementation in the load balancer registry so that it can be referred to from the service config
- Parse the JSON configuration object of your implementation. This allows your load balancer to be configured in the service config with any arbitrary JSON you choose to support
- Manage what backends to maintain a connection with
- Implement a picker that will choose which backend to connect to when an RPC is made. Note that this needs to be a fast operation as it is on the RPC call path
- To enable your load balancer, configure it in your service config

Refer the gRPC documentation for more details https://grpc.io/docs/guides/custom-load-balancing/
15 changes: 15 additions & 0 deletions examples/src/main/java/io/grpc/examples/deadline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
gRPC Deadline Example
=====================

A Deadline is used to specify a point in time past which a client is unwilling to wait for a response from a server.
This simple idea is very important in building robust distributed systems.
Clients that do not wait around unnecessarily and servers that know when to give up processing requests will improve the resource utilization and latency of your system.

Note that while some language APIs have the concept of a deadline, others use the idea of a timeout.
When an API asks for a deadline, you provide a point in time which the call should not go past.
A timeout is the max duration of time that the call can take.
A timeout can be converted to a deadline by adding the timeout to the current time when the application starts a call.

This Example gives usage and implementation of Deadline on Server, Client and Propagation.

Refer the gRPC documentation for more details on Deadlines https://grpc.io/docs/guides/deadlines/
16 changes: 16 additions & 0 deletions examples/src/main/java/io/grpc/examples/errordetails/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
gRPC Error Details Example
=====================

If a gRPC call completes successfully the server returns an OK status to the client (depending on the language the OK status may or may not be directly used in your code).
But what happens if the call isn’t successful?

This Example gives the usage and implementation of how return the error details if gRPC call not successful or fails
and how to set and read com.google.rpc.Status objects as google.rpc.Status error details.

gRPC allows detailed error information to be encapsulated in protobuf messages, which are sent alongside the status codes.

If an error occurs, gRPC returns one of its error status codes with error message that provides further error details about what happened.

Refer the below links for more details on error details and status codes
- https://grpc.io/docs/guides/error/
- https://github.com/grpc/grpc-java/blob/master/api/src/main/java/io/grpc/Status.java
27 changes: 27 additions & 0 deletions examples/src/main/java/io/grpc/examples/errorhandling/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
gRPC Error Handling Example
=====================

Error handling in gRPC is a critical aspect of designing reliable and robust distributed systems.
gRPC provides a standardized mechanism for handling errors using status codes, error details, and optional metadata.

This Example gives the usage and implementation of how to handle the Errors/Exceptions in gRPC,
shows how to extract error information from a failed RPC and setting and reading RPC error details.

If a gRPC call completes successfully the server returns an OK status to the client (depending on the language the OK status may or may not be directly used in your code).

If an error occurs gRPC returns one of its error status codes with error message that provides further error details about what happened.

Error Propagation:
- When an error occurs on the server, gRPC stops processing the RPC and sends the error (status code, description, and optional details) to the client.
- On the client side, the error can be handled based on the status code.

Client Side Error Handling:
- The gRPC client typically throws an exception or returns an error object when an RPC fails.

Server Side Error Handling:
- Servers use the gRPC API to return errors explicitly using the grpc library's status functions.

gRPC uses predefined status codes to represent the outcome of an RPC call. These status codes are part of the Status object that is sent from the server to the client.
Each status code is accompanied by a human-readable description(Please refer https://github.com/grpc/grpc-java/blob/master/api/src/main/java/io/grpc/Status.java)

Refer the gRPC documentation for more details on Error Handling https://grpc.io/docs/guides/error/
13 changes: 13 additions & 0 deletions examples/src/main/java/io/grpc/examples/experimental/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
gRPC Compression Example
=====================

This example shows how clients can specify compression options when performing RPCs,
and how to enable compressed(i,e gzip) requests/responses for only particular method and in case of all methods by using the interceptors.

Compression is used to reduce the amount of bandwidth used when communicating between client/server or peers and
can be enabled or disabled based on call or message level for all languages.

gRPC allows asymmetrically compressed communication, whereby a response may be compressed differently with the request,
or not compressed at all.

Refer the gRPC documentation for more details on Compression https://grpc.io/docs/guides/compression/
22 changes: 22 additions & 0 deletions examples/src/main/java/io/grpc/examples/grpcproxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
gRPC Proxy Example
=====================

A gRPC proxy is a component or tool that acts as an intermediary between gRPC clients and servers,
facilitating communication while offering additional capabilities.
Proxies are used in scenarios where you need to handle tasks like load balancing, routing, monitoring,
or providing a bridge between gRPC and other protocols.

GrpcProxy itself can be used unmodified to proxy any service for both unary and streaming.
It doesn't care what type of messages are being used.
The Registry class causes it to be called for any inbound RPC, and uses plain bytes for messages which avoids marshalling
messages and the need for Protobuf schema information.

We can run the Grpc Proxy with Route guide example to see how it works by running the below

Route guide has unary and streaming RPCs which makes it a nice showcase, and we can run each in a separate terminal window.

./build/install/examples/bin/route-guide-server
./build/install/examples/bin/grpc-proxy
./build/install/examples/bin/route-guide-client localhost:8981

you can verify the proxy is being used by shutting down the proxy and seeing the client fail.
16 changes: 16 additions & 0 deletions examples/src/main/java/io/grpc/examples/header/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
gRPC Custom Header Example
=====================

This example gives the usage and implementation of how to create and process(send/receive) the custom headers between Client and Server
using the interceptors (HeaderServerInterceptor, ClientServerInterceptor) along with Metadata.

Metadata is a side channel that allows clients and servers to provide information to each other that is associated with an RPC.
gRPC metadata is a key-value pair of data that is sent with initial or final gRPC requests or responses.
It is used to provide additional information about the call, such as authentication credentials,
tracing information, or custom headers.

gRPC metadata can be used to send custom headers to the server or from the server to the client.
This can be used to implement application-specific features, such as load balancing,
rate limiting or providing detailed error messages from the server to the client.

Refer the gRPC documentation for more on Metadata/Headers https://grpc.io/docs/guides/metadata/
10 changes: 10 additions & 0 deletions examples/src/main/java/io/grpc/examples/healthservice/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
gRPC Health Service Example
=====================

The Health Service example provides a HelloWorld gRPC server that doesn't like short names along with a
health service. It also provides a client application which makes HelloWorld
calls and checks the health status.

The client application also shows how the round robin load balancer can
utilize the health status to avoid making calls to a service that is
not actively serving.
59 changes: 59 additions & 0 deletions examples/src/main/java/io/grpc/examples/hedging/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
gRPC Hedging Example
=====================

The Hedging example demonstrates that enabling hedging
can reduce tail latency. (Users should note that enabling hedging may introduce other overhead;
and in some scenarios, such as when some server resource gets exhausted for a period of time and
almost every RPC during that time has high latency or fails, hedging may make things worse.
Setting a throttle in the service config is recommended to protect the server from too many
inappropriate retry or hedging requests.)

The server and the client in the example are basically the same as those in the
[hello world](src/main/java/io/grpc/examples/helloworld) example, except that the server mimics a
long tail of latency, and the client sends 2000 requests and can turn on and off hedging.

To mimic the latency, the server randomly delays the RPC handling by 2 seconds at 10% chance, 5
seconds at 5% chance, and 10 seconds at 1% chance.

When running the client enabling the following hedging policy

```json
"hedgingPolicy": {
"maxAttempts": 3,
"hedgingDelay": "1s"
}
```
Then the latency summary in the client log is like the following

```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging enabled]
========================
50% latency: 0ms
90% latency: 6ms
95% latency: 1,003ms
99% latency: 2,002ms
99.9% latency: 2,011ms
Max latency: 5,272ms
========================
```

See [the section below](#to-build-the-examples) for how to build and run the example. The
executables for the server and the client are `hedging-hello-world-server` and
`hedging-hello-world-client`.

To disable hedging, set environment variable `DISABLE_HEDGING_IN_HEDGING_EXAMPLE=true` before
running the client. That produces a latency summary in the client log like the following

```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging disabled]
========================
50% latency: 0ms
90% latency: 2,002ms
95% latency: 5,002ms
99% latency: 10,004ms
99.9% latency: 10,007ms
Max latency: 10,007ms
========================
```
7 changes: 7 additions & 0 deletions examples/src/main/java/io/grpc/examples/helloworld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
gRPC Hello World Example
=====================
This Example gives the details about basic implementation of gRPC Client and Server along with
how the communication happens between them by sending a greeting message.

Refer the gRPC documentation for more details on helloworld.proto specification, creation of gRPC services and
methods along with Execution process https://grpc.io/docs/languages/java/quickstart/
Loading

0 comments on commit 9e86299

Please sign in to comment.