Skip to content

Instantly share code, notes, and snippets.

@tam7t
Last active May 20, 2022 17:46
Show Gist options
  • Save tam7t/8cdd4df09c31b5364bc3850a9982296f to your computer and use it in GitHub Desktop.
Save tam7t/8cdd4df09c31b5364bc3850a9982296f to your computer and use it in GitHub Desktop.
grpd-status-demo
module github.com/tam7t/grpc-demo
go 1.17
require (
google.golang.org/grpc v1.40.0
google.golang.org/grpc/examples v0.0.0-20220215234149-ec717cad7395
)
require (
github.com/golang/protobuf v1.5.2 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8 // indirect
google.golang.org/protobuf v1.27.1 // indirect
)
package main
import (
"context"
"errors"
"log"
"net"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/status"
)
// For more details see:
// https://github.com/grpc/grpc/blob/master/doc/service_config.md
const ServiceConfig = `
{
"methodConfig": [
{
"name": [{"service": "helloworld.Greeter"}],
"waitForReady": true,
"retryPolicy": {
"MaxAttempts": 3,
"InitialBackoff": "1s",
"MaxBackoff": "10s",
"BackoffMultiplier": 1.1,
"RetryableStatusCodes": [ "UNAVAILABLE" ]
}
}
]
}
`
func main() {
// support ctrl+c shutdown
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
// setup tmpdir for unix socket
tmpDir, err := os.MkdirTemp("", "ut")
if err != nil {
log.Fatalf("couldnt make tmpdir: %+v", err)
}
path := filepath.Join(tmpDir, "server.sock")
defer os.Remove(path)
defer os.RemoveAll(tmpDir)
// start server
lis, err := net.Listen("unix", path)
if err != nil {
log.Fatalf("couldnt listen: %+v", err)
}
defer lis.Close()
log.Printf("server listening at %v", lis.Addr())
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
go func() {
// TODO: use grpc.ErrServerStopped to print success message
if err := s.Serve(lis); err != nil {
log.Printf("failed to serve: %v", err)
}
}()
log.Println("waiting...")
// send a request every 2 seconds
conn, err := grpc.Dial(path,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithContextDialer(func(ctx context.Context, target string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, "unix", target)
}),
grpc.WithDefaultServiceConfig(ServiceConfig),
)
if err != nil {
log.Fatalf("couldnt dial server: %+v", err)
}
defer conn.Close()
client := pb.NewGreeterClient(conn)
ticker := time.NewTicker(2 * time.Second)
go func() {
for {
select {
case <-ctx.Done():
log.Println("client shutdown")
return
case <-ticker.C:
// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
r, err := client.SayHello(ctx, &pb.HelloRequest{Name: "foo"})
if err != nil {
log.Printf("could not greet: %v", err)
log.Printf("error code: %s", status.Code(err))
}
log.Printf("Greeting: %s", r.GetMessage())
}
}
}()
// block on ctrl+c
<-ctx.Done()
s.GracefulStop()
}
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
// return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
// return nil, status.Error(codes.Unavailable, "unavailabe test!")
return nil, errors.New("bad request foo")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment