diff --git a/src/productcatalogservice/README.md b/src/productcatalogservice/README.md index 13ff37c..5dc8fea 100644 --- a/src/productcatalogservice/README.md +++ b/src/productcatalogservice/README.md @@ -29,3 +29,10 @@ kubectl exec \ $(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \ -c server -- kill -USR2 1 ``` + +## Latency injection + +This service has an `EXTRA_LATENCY` environment variable. This will inject a sleep for the specified [time.Duration](https://golang.org/pkg/time/#ParseDuration) on every call to +to the server. + +For example, use `EXTRA_LATENCY="5.5s"` to sleep for 5.5 seconds on every request. diff --git a/src/productcatalogservice/server.go b/src/productcatalogservice/server.go index 4fb7018..c55e0af 100644 --- a/src/productcatalogservice/server.go +++ b/src/productcatalogservice/server.go @@ -48,6 +48,7 @@ var ( cat pb.ListProductsResponse catalogMutex *sync.Mutex log *logrus.Logger + extraLatency time.Duration port = flag.Int("port", 3550, "port to listen at") @@ -77,6 +78,18 @@ func main() { go initProfiling("productcatalogservice", "1.0.0") flag.Parse() + // set injected latency + if s := os.Getenv("EXTRA_LATENCY"); s != "" { + v, err := time.ParseDuration(s) + if err != nil { + log.Fatalf("failed to parse EXTRA_LATENCY (%s) as time.Duration: %+v", v, err) + } + extraLatency = v + log.Infof("extra latency enabled (duration: %v)", extraLatency) + } else { + extraLatency = time.Duration(0) + } + sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGUSR1, syscall.SIGUSR2) go func() { @@ -117,7 +130,6 @@ func initJaegerTracing() { log.Info("jaeger initialization disabled.") return } - // Register the Jaeger exporter to be able to retrieve // the collected spans. exporter, err := jaeger.NewExporter(jaeger.Options{ @@ -226,10 +238,12 @@ func (p *productCatalog) Check(ctx context.Context, req *healthpb.HealthCheckReq } func (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) { + time.Sleep(extraLatency) return &pb.ListProductsResponse{Products: parseCatalog()}, nil } func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { + time.Sleep(extraLatency) var found *pb.Product for i := 0; i < len(parseCatalog()); i++ { if req.Id == parseCatalog()[i].Id { @@ -243,6 +257,7 @@ func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductReque } func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) { + time.Sleep(extraLatency) // Intepret query as a substring match in name or description. var ps []*pb.Product for _, p := range parseCatalog() {