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  }