github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2015/gotham-grpc/backend/backend.go (about) 1 // Tha backend command runs a Google server that returns fake results. 2 package main 3 4 import ( 5 "flag" 6 "fmt" 7 "log" 8 "math/rand" 9 "net" 10 "net/http" 11 _ "net/http/pprof" 12 "time" 13 14 "golang.org/x/net/context" 15 "golang.org/x/net/trace" 16 pb "golang.org/x/talks/2015/gotham-grpc/search" 17 "google.golang.org/grpc" 18 ) 19 20 var ( 21 index = flag.Int("index", 0, "RPC port is 36061+index; debug port is 36661+index") 22 ) 23 24 type server struct{} 25 26 // randomDuration returns a random duration up to max, at intervals of max/10. 27 func randomDuration(max time.Duration) time.Duration { 28 return time.Duration(1+int64(rand.Intn(10))) * (max / 10) 29 } 30 31 // Search sleeps for a random interval then returns a string 32 // identifying the query and this backend. 33 func (s *server) Search(ctx context.Context, req *pb.Request) (*pb.Result, error) { // HL 34 d := randomDuration(100 * time.Millisecond) 35 logSleep(ctx, d) // HL 36 select { 37 case <-time.After(d): 38 return &pb.Result{ // HL 39 Title: fmt.Sprintf("result for [%s] from backend %d", req.Query, *index), // HL 40 }, nil // HL 41 case <-ctx.Done(): 42 return nil, ctx.Err() 43 } 44 } 45 46 func logSleep(ctx context.Context, d time.Duration) { 47 if tr, ok := trace.FromContext(ctx); ok { // HL 48 tr.LazyPrintf("sleeping for %s", d) // HL 49 } 50 } 51 52 // Watch returns a stream of results identifying the query and this 53 // backend, sleeping a random interval between each send. 54 func (s *server) Watch(req *pb.Request, stream pb.Google_WatchServer) error { // HL 55 ctx := stream.Context() 56 for i := 0; ; i++ { 57 d := randomDuration(1 * time.Second) 58 logSleep(ctx, d) // HL 59 select { 60 case <-time.After(d): 61 err := stream.Send(&pb.Result{ // HL 62 Title: fmt.Sprintf("result %d for [%s] from backend %d", i, req.Query, *index), // HL 63 }) // HL 64 if err != nil { 65 return err 66 } 67 case <-ctx.Done(): 68 return ctx.Err() 69 } 70 } 71 } 72 73 func main() { 74 flag.Parse() 75 rand.Seed(time.Now().UnixNano()) 76 go http.ListenAndServe(fmt.Sprintf(":%d", 36661+*index), nil) // HTTP debugging 77 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 36061+*index)) // RPC port // HL 78 if err != nil { 79 log.Fatalf("failed to listen: %v", err) 80 } 81 g := grpc.NewServer() // HL 82 pb.RegisterGoogleServer(g, new(server)) // HL 83 g.Serve(lis) // HL 84 }