Skip to content

Commit 45088c2

Browse files
authored
examples: fix concurrent map accesses in route_guide server (grpc#1752)
1 parent 4e393e0 commit 45088c2

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

examples/route_guide/server/server.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"log"
3434
"math"
3535
"net"
36+
"sync"
3637
"time"
3738

3839
"golang.org/x/net/context"
@@ -55,8 +56,10 @@ var (
5556
)
5657

5758
type routeGuideServer struct {
58-
savedFeatures []*pb.Feature
59-
routeNotes map[string][]*pb.RouteNote
59+
savedFeatures []*pb.Feature // read-only after initialized
60+
61+
mu sync.Mutex // protects routeNotes
62+
routeNotes map[string][]*pb.RouteNote
6063
}
6164

6265
// GetFeature returns the feature at the given point.
@@ -130,12 +133,17 @@ func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error
130133
return err
131134
}
132135
key := serialize(in.Location)
133-
if _, present := s.routeNotes[key]; !present {
134-
s.routeNotes[key] = []*pb.RouteNote{in}
135-
} else {
136-
s.routeNotes[key] = append(s.routeNotes[key], in)
137-
}
138-
for _, note := range s.routeNotes[key] {
136+
137+
s.mu.Lock()
138+
s.routeNotes[key] = append(s.routeNotes[key], in)
139+
// Note: this copy prevents blocking other clients while serving this one.
140+
// We don't need to do a deep copy, because elements in the slice are
141+
// insert-only and never modified.
142+
rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
143+
copy(rn, s.routeNotes[key])
144+
s.mu.Unlock()
145+
146+
for _, note := range rn {
139147
if err := stream.Send(note); err != nil {
140148
return err
141149
}
@@ -201,9 +209,8 @@ func serialize(point *pb.Point) string {
201209
}
202210

203211
func newServer() *routeGuideServer {
204-
s := new(routeGuideServer)
212+
s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
205213
s.loadFeatures(*jsonDBFile)
206-
s.routeNotes = make(map[string][]*pb.RouteNote)
207214
return s
208215
}
209216

0 commit comments

Comments
 (0)