Skip to content

Commit d461534

Browse files
authored
Fix almost everything (#46)
Fix almost everything
1 parent 2a5c19b commit d461534

File tree

2 files changed

+60
-38
lines changed

2 files changed

+60
-38
lines changed

codelabs/grpc-go-streaming/README.md

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ and easy interface updating.
5555
* For installation instructions, see Go’s [Getting Started](https://golang.org/doc/install) guide.
5656
* [**Protocol buffer**](https://developers.google.com/protocol-buffers) **compiler**, `protoc`, [version 3](https://protobuf.dev/programming-guides/proto3).
5757
* For installation instructions, see [Protocol Buffer Compiler Installation](https://grpc.io/docs/protoc-installation/).
58+
* NOTE: Must need a version of Protoc 3.27.1 or higher.
5859
* **Go plugins** for the protocol compiler:
5960
* Install the protocol compiler plugins for Go using the following commands.
6061

@@ -227,7 +228,7 @@ rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
227228
```
228229

229230
> [!TIP]
230-
> For the complete .proto file, see [routeguide/route_guide.proto](/completed/routeguide/route_guide.proto).
231+
> For the complete .proto file, see [routeguide/route_guide.proto](https://github.com/grpc-ecosystem/grpc-codelabs/blob/bdabe90d07065752a66cf449c2513803b35e6cd3/codelabs/grpc-go-streaming/completed/routeguide/route_guide.pb.go).
231232
232233
## Generating client and server code
233234

@@ -394,8 +395,17 @@ func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error
394395
return err
395396
}
396397
key := serialize(in.Location)
397-
... // look for notes to be sent to client
398-
for _, note := range s.routeNotes[key] {
398+
399+
s.mu.Lock()
400+
s.routeNotes[key] = append(s.routeNotes[key], in)
401+
// Note: this copy prevents blocking other clients while serving this one.
402+
// We don't need to do a deep copy, because elements in the slice are
403+
// insert-only and never modified.
404+
rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
405+
copy(rn, s.routeNotes[key])
406+
s.mu.Unlock()
407+
408+
for _, note := range rn {
399409
if err := stream.Send(note); err != nil {
400410
return err
401411
}
@@ -424,16 +434,16 @@ do this for our `RouteGuide` service:
424434
> port can be configured by passing in `port` flag. Defaults to `50051`
425435
426436
```go
427-
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
437+
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
428438
if err != nil {
429439
log.Fatalf("failed to listen: %v", err)
430440
}
431-
var opts []grpc.ServerOption
432-
grpcServer := grpc.NewServer(opts...)
433441

434-
s := &routeGuideServer{}
442+
grpcServer := grpc.NewServer()
443+
444+
s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
435445
s.loadFeatures()
436-
pb.RegisterRouteGuideServer(grpcServer, newServer())
446+
pb.RegisterRouteGuideServer(grpcServer, s)
437447
grpcServer.Serve(lis)
438448
```
439449

@@ -464,6 +474,7 @@ with the server. We create this by passing the server address and port number to
464474
> serverAddr can be configured by passing in `addr` flag. Defaults to `localhost:50051`
465475
466476
```go
477+
// Set up a connection to the gRPC server.
467478
conn, err := grpc.NewClient("dns:///"+*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
468479
if err != nil {
469480
log.Fatalf("fail to dial: %v", err)
@@ -480,6 +491,7 @@ making Go function calls. We get it using the `NewRouteGuideClient` method
480491
provided by the pb package generated from the example `.proto` file.
481492

482493
```go
494+
// Create a new RouteGuide stub.
483495
client := pb.NewRouteGuideClient(conn)
484496
```
485497

@@ -496,19 +508,23 @@ returns a stream of geographical `Feature`s.
496508

497509
```go
498510
rect := &pb.Rectangle{ ... } // initialize a pb.Rectangle
511+
log.Printf("Looking for features within %v", rect)
499512
stream, err := client.ListFeatures(context.Background(), rect)
500513
if err != nil {
501-
...
514+
log.Fatalf("client.ListFeatures failed: %v", err)
502515
}
503516
for {
504-
feature, err := stream.Recv()
505-
if err == io.EOF {
506-
break
507-
}
508-
if err != nil {
509-
log.Fatalf("%v.ListFeatures(_) = _, %v", client, err)
510-
}
511-
log.Println(feature)
517+
// For server-to-client streaming RPCs, you call stream.Recv() until it
518+
// returns io.EOF.
519+
feature, err := stream.Recv()
520+
if err == io.EOF {
521+
break
522+
}
523+
if err != nil {
524+
log.Fatalf("client.ListFeatures failed: %v", err)
525+
}
526+
log.Printf("Feature: name: %q, point:(%v, %v)", feature.GetName(),
527+
feature.GetLocation().GetLatitude(), feature.GetLocation().GetLongitude())
512528
}
513529
```
514530

@@ -539,18 +555,20 @@ for i := 0; i < pointCount; i++ {
539555
points = append(points, randomPoint(r))
540556
}
541557
log.Printf("Traversing %d points.", len(points))
542-
stream, err := client.RecordRoute(context.Background())
558+
c2sStream, err := client.RecordRoute(context.TODO())
543559
if err != nil {
544-
log.Fatalf("%v.RecordRoute(_) = _, %v", client, err)
560+
log.Fatalf("client.RecordRoute failed: %v", err)
545561
}
562+
// Stream each point to the server.
546563
for _, point := range points {
547-
if err := stream.Send(point); err != nil {
548-
log.Fatalf("%v.Send(%v) = %v", stream, point, err)
564+
if err := c2sStream.Send(point); err != nil {
565+
log.Fatalf("client.RecordRoute: stream.Send(%v) failed: %v", point, err)
549566
}
550567
}
551-
reply, err := stream.CloseAndRecv()
568+
// Close the stream and receive the RouteSummary from the server.
569+
reply, err := c2sStream.CloseAndRecv()
552570
if err != nil {
553-
log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)
571+
log.Fatalf("client.RecordRoute failed: %v", err)
554572
}
555573
log.Printf("Route summary: %v", reply)
556574
```
@@ -572,29 +590,36 @@ return values via our method’s stream while the server is still writing messag
572590
to their message stream.
573591

574592
```go
575-
stream, err := client.RouteChat(context.Background())
576-
waitc := make(chan struct{})
593+
biDiStream, err := client.RouteChat(context.Background())
594+
if err != nil {
595+
log.Fatalf("client.RouteChat failed: %v", err)
596+
}
597+
// this channal is used to wait for the receive goroutine to finish.
598+
recvDoneCh := make(chan struct{})
599+
// receive goroutine.
577600
go func() {
578601
for {
579-
in, err := stream.Recv()
602+
in, err := biDiStream.Recv()
580603
if err == io.EOF {
581604
// read done.
582-
close(waitc)
605+
close(recvDoneCh)
583606
return
584607
}
585608
if err != nil {
586-
log.Fatalf("Failed to receive a note : %v", err)
609+
log.Fatalf("client.RouteChat failed: %v", err)
587610
}
588611
log.Printf("Got message %s at point(%d, %d)", in.Message, in.Location.Latitude, in.Location.Longitude)
589612
}
590613
}()
614+
// send messages simultaneously.
591615
for _, note := range notes {
592-
if err := stream.Send(note); err != nil {
593-
log.Fatalf("Failed to send a note: %v", err)
616+
if err := biDiStream.Send(note); err != nil {
617+
log.Fatalf("client.RouteChat: stream.Send(%v) failed: %v", note, err)
594618
}
595619
}
596-
stream.CloseSend()
597-
<-waitc
620+
biDiStream.CloseSend()
621+
// wait for the receive goroutine to finish.
622+
<-recvDoneCh
598623
```
599624

600625
The syntax for reading and writing here is very similar to our client-side

codelabs/grpc-go-streaming/completed/client/client.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ func main() {
2929
// Create a new RouteGuide stub.
3030
client := pb.NewRouteGuideClient(conn)
3131

32-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
33-
defer cancel()
34-
3532
///////////////////////////////////////////////////////////////////////////
3633
// Server-to-Client Streaming RPC
3734
//
@@ -42,7 +39,7 @@ func main() {
4239
Hi: &pb.Point{Latitude: 420000000, Longitude: -730000000},
4340
}
4441
log.Printf("Looking for features within %v", rect)
45-
stream, err := client.ListFeatures(ctx, rect)
42+
stream, err := client.ListFeatures(context.Background(), rect)
4643
if err != nil {
4744
log.Fatalf("client.ListFeatures failed: %v", err)
4845
}
@@ -74,7 +71,7 @@ func main() {
7471
}
7572
log.Printf("Traversing %d points.", len(points))
7673
// Call RecordRoute method on the client.
77-
c2sStream, err := client.RecordRoute(ctx)
74+
c2sStream, err := client.RecordRoute(context.Background())
7875
if err != nil {
7976
log.Fatalf("client.RecordRoute failed: %v", err)
8077
}
@@ -105,7 +102,7 @@ func main() {
105102
{Location: &pb.Point{Latitude: 0, Longitude: 3}, Message: "Sixth message"},
106103
}
107104
// Call RouteChat method on the client.
108-
biDiStream, err := client.RouteChat(ctx)
105+
biDiStream, err := client.RouteChat(context.Background())
109106
if err != nil {
110107
log.Fatalf("client.RouteChat failed: %v", err)
111108
}

0 commit comments

Comments
 (0)