Skip to content

Commit 34c46e8

Browse files
committed
use ServerStreaming scenario to demonstrate graceful shutdown
1 parent 5ee5e3b commit 34c46e8

File tree

3 files changed

+34
-33
lines changed

3 files changed

+34
-33
lines changed
+15-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
# Graceful Stop
22

33
This example demonstrates how to gracefully stop a gRPC server using
4-
Server.GracefulStop().
4+
`Server.GracefulStop()`.
55

66
## How to run
77

8-
Start the server which will listen to incoming gRPC requests as well as OS
9-
interrupt signals (SIGINT/SIGTERM). After receiving interrupt signal, it calls
10-
`s.GracefulStop()` to gracefully shut down the server. If graceful shutdown
11-
doesn't happen in time, server is stopped forcefully.
8+
Start the server which will serve `ServerStreaming` gRPC requests as well as an
9+
OS interrupt signal (SIGINT/SIGTERM). `ServerStreaming` handler returns an
10+
error after sending 5 messages to the client or if client's context is
11+
canceled. If an interrupt signal is received, it calls `s.GracefulStop()` to
12+
gracefully shut down the server. If graceful shutdown doesn't happen in time,
13+
the server is stopped forcefully.
1214

1315
```sh
1416
$ go run server/main.go
1517
```
1618

17-
In a separate terminal, start the client which will send multiple requests to
18-
the server with some delay between each request.
19+
In a separate terminal, start the client which will start `ServerStreaming`
20+
request to the server and keep receiving messages until an error is received.
21+
Once an error is received, it closes the stream.
1922

2023
```sh
2124
$ go run client/main.go
2225
```
2326

24-
Use Ctrl+C or SIGTERM to signal the server to shut down.
27+
Once the client starts receiving messages from server, use Ctrl+C or SIGTERM to
28+
signal the server to shut down.
2529

26-
The server begins a graceful stop:
27-
- It finishes ongoing requests.
28-
- Rejects new incoming requests.
29-
30-
The client will notice the server's shutdown when a request fails.
30+
The server begins a graceful stop. It finish the in-flight request. In this
31+
case, client will receive 5 messages followed by the stream failure from the
32+
server, allowing client to close the stream gracefully, before shutting down.
3133

examples/features/gracefulstop/client/main.go

+19-17
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,43 @@ import (
2626
"time"
2727

2828
"google.golang.org/grpc"
29-
"google.golang.org/grpc/codes"
3029
"google.golang.org/grpc/credentials/insecure"
31-
pb "google.golang.org/grpc/examples/helloworld/helloworld"
32-
"google.golang.org/grpc/status"
30+
pb "google.golang.org/grpc/examples/features/proto/echo"
3331
)
3432

3533
var addr = flag.String("addr", "localhost:50052", "the address to connect to")
3634

3735
func main() {
3836
flag.Parse()
3937

40-
// Set up a connection to the server.
4138
conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
4239
if err != nil {
43-
log.Fatalf("Failed to connect: %v", err)
40+
log.Fatalf("Failed to create new client: %v", err)
4441
}
4542
defer conn.Close()
46-
c := pb.NewGreeterClient(conn)
43+
c := pb.NewEchoClient(conn)
4744

48-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
45+
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
4946
defer cancel()
5047

51-
for i := 1; i <= 10; i++ {
52-
log.Printf("Calling SayHello %d time", i)
53-
r, err := c.SayHello(ctx, &pb.HelloRequest{})
48+
stream, err := c.ServerStreamingEcho(ctx, &pb.EchoRequest{})
49+
if err != nil {
50+
log.Fatalf("Error starting stream: %v", err)
51+
}
52+
53+
for {
54+
r, err := stream.Recv()
5455
if err != nil {
55-
if status.Code(err) != codes.InvalidArgument {
56-
log.Printf("Received unexpected error: %v", err)
57-
continue
56+
// Handle the error and close the stream gracefully
57+
log.Printf("Error sending request: %v\n", err)
58+
err := stream.CloseSend()
59+
if err != nil {
60+
log.Fatalf("Error closing stream: %v", err)
5861
}
59-
log.Printf("Received error: %v", err)
60-
continue
62+
log.Println("Stream closed gracefully")
63+
break
6164
}
62-
log.Printf("Received response: %s", r.Message)
63-
time.Sleep(time.Second)
65+
log.Printf(r.Message)
6466
}
6567

6668
log.Printf("Client finished interaction with server.")

examples/features/gracefulstop/server/main.go

-3
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,12 @@ func (s *server) ServerStreamingEcho(_ *pb.EchoRequest, stream pb.Echo_ServerStr
6060
atomic.AddInt32(&streamMessages, 1)
6161

6262
mu.Lock()
63-
6463
if streamMessages > 5 {
6564
return fmt.Errorf("request failed")
6665
}
67-
6866
if err := stream.Send(&pb.EchoResponse{Message: fmt.Sprintf("Messages Sent: %d", streamMessages)}); err != nil {
6967
return err
7068
}
71-
7269
mu.Unlock()
7370

7471
time.Sleep(1 * time.Second)

0 commit comments

Comments
 (0)