Changed product catalog to use json, so that it slows down and generates nice profiles

This commit is contained in:
morganmclean 2018-07-17 21:35:11 -07:00
parent 2713f47bbb
commit dbc9523cea

View file

@ -10,7 +10,9 @@ import (
"time" "time"
pb "./genproto" pb "./genproto"
"cloud.google.com/go/profiler" "cloud.google.com/go/profiler"
"github.com/golang/protobuf/jsonpb"
"go.opencensus.io/exporter/stackdriver" "go.opencensus.io/exporter/stackdriver"
"go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/plugin/ocgrpc"
"go.opencensus.io/trace" "go.opencensus.io/trace"
@ -21,71 +23,107 @@ import (
var port = flag.Int("port", 3550, "port to listen at") var port = flag.Int("port", 3550, "port to listen at")
var catalog = []*pb.Product{ const catalogJSON = `{
{ "products": [
Id: "OLJCESPC7Z", {
Name: "Vintage Typewriter", "id": "OLJCESPC7Z",
Description: "This typewriter looks good in your living room.", "name": "Vintage Typewriter",
Picture: "/static/img/products/typewriter.jpg", "description": "This typewriter looks good in your living room.",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 67, Nanos: 990000000}, "picture": "/static/img/products/typewriter.jpg",
}, "priceUsd": {
{ "currencyCode": "USD",
Id: "66VCHSJNUP", "units": 67,
Name: "Vintage Camera Lens", "nanos": 990000000
Description: "You won't have a camera to use it and it probably doesn't work anyway.", }
Picture: "/static/img/products/camera-lens.jpg", },
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 12, Nanos: 490000000}, {
}, "id": "66VCHSJNUP",
{ "name": "Vintage Camera Lens",
Id: "1YMWWN1N4O", "description": "You won't have a camera to use it and it probably doesn't work anyway.",
Name: "Home Barista Kit", "picture": "/static/img/products/camera-lens.jpg",
Description: "Always wanted to brew coffee with Chemex and Aeropress at home?", "priceUsd": {
Picture: "/static/img/products/barista-kit.jpg", "currencyCode": "USD",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 124, Nanos: 0}, "units": 12,
}, "nanos": 490000000
{ }
Id: "L9ECAV7KIM", },
Name: "Terrarium", {
Description: "This terrarium will looks great in your white painted living room.", "id": "1YMWWN1N4O",
Picture: "/static/img/products/terrarium.jpg", "name": "Home Barista Kit",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 36, Nanos: 450000000}, "description": "Always wanted to brew coffee with Chemex and Aeropress at home?",
}, "picture": "/static/img/products/barista-kit.jpg",
{ "priceUsd": {
Id: "2ZYFJ3GM2N", "currencyCode": "USD",
Name: "Film Camera", "units": 124
Description: "This camera looks like it's a film camera, but it's actually digital.", }
Picture: "/static/img/products/film-camera.jpg", },
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 2245, Nanos: 00000000}, {
}, "id": "L9ECAV7KIM",
{ "name": "Terrarium",
Id: "0PUK6V6EV0", "description": "This terrarium will looks great in your white painted living room.",
Name: "Vintage Record Player", "picture": "/static/img/products/terrarium.jpg",
Description: "It still works.", "priceUsd": {
Picture: "/static/img/products/record-player.jpg", "currencyCode": "USD",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 65, Nanos: 500000000}, "units": 36,
}, "nanos": 450000000
{ }
Id: "LS4PSXUNUM", },
Name: "Metal Camping Mug", {
Description: "You probably don't go camping that often but this is better than plastic cups.", "id": "2ZYFJ3GM2N",
Picture: "/static/img/products/camp-mug.jpg", "name": "Film Camera",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 24, Nanos: 330000000}, "description": "This camera looks like it's a film camera, but it's actually digital.",
}, "picture": "/static/img/products/film-camera.jpg",
{ "priceUsd": {
Id: "9SIQT8TOJO", "currencyCode": "USD",
Name: "City Bike", "units": 2245
Description: "This single gear bike probably cannot climb the hills of San Francisco.", }
Picture: "/static/img/products/city-bike.jpg", },
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 789, Nanos: 500000000}, {
}, "id": "0PUK6V6EV0",
{ "name": "Vintage Record Player",
Id: "6E92ZMYYFZ", "description": "It still works.",
Name: "Air Plant", "picture": "/static/img/products/record-player.jpg",
Description: "Have you ever wondered whether air plants need water? Buy one and figure out.", "priceUsd": {
Picture: "/static/img/products/air-plant.jpg", "currencyCode": "USD",
PriceUsd: &pb.Money{CurrencyCode: "USD", Units: 12, Nanos: 300000000}, "units": 65,
}, "nanos": 500000000
} }
},
{
"id": "LS4PSXUNUM",
"name": "Metal Camping Mug",
"description": "You probably don't go camping that often but this is better than plastic cups.",
"picture": "/static/img/products/camp-mug.jpg",
"priceUsd": {
"currencyCode": "USD",
"units": 24,
"nanos": 330000000
}
},
{
"id": "9SIQT8TOJO",
"name": "City Bike",
"description": "This single gear bike probably cannot climb the hills of San Francisco.",
"picture": "/static/img/products/city-bike.jpg",
"priceUsd": {
"currencyCode": "USD",
"units": 789,
"nanos": 500000000
}
},
{
"id": "6E92ZMYYFZ",
"name": "Air Plant",
"description": "Have you ever wondered whether air plants need water? Buy one and figure out.",
"picture": "/static/img/products/air-plant.jpg",
"priceUsd": {
"currencyCode": "USD",
"units": 12,
"nanos": 300000000
}
}
]
}`
func main() { func main() {
go initTracing() go initTracing()
@ -136,36 +174,51 @@ func initProfiling(service, version string) {
Service: service, Service: service,
ServiceVersion: version, ServiceVersion: version,
// ProjectID must be set if not running on GCP. // ProjectID must be set if not running on GCP.
// ProjectID: "my-project", ProjectID: "oval-time-515",
}); err != nil { }); err != nil {
log.Printf("warn: failed to start profiler: %+v", err) log.Printf("warn: failed to start profiler: %+v", err)
d := time.Second * 10 * time.Duration(i)
log.Printf("sleeping %v to retry initializing stackdriver profiler", d)
time.Sleep(d)
continue
} }
d := time.Second * 10 * time.Duration(i) return
log.Printf("sleeping %v to retry initializing stackdriver profiler", d)
time.Sleep(d)
} }
log.Printf("warning: could not initialize stackdriver profiler after retrying, giving up") log.Printf("warning: could not initialize stackdriver profiler after retrying, giving up")
} }
type productCatalog struct{} type productCatalog struct{}
func (p *productCatalog) catalog() []*pb.Product {
var cat pb.ListProductsResponse
if err := jsonpb.UnmarshalString(catalogJSON, &cat); err != nil {
log.Printf("warning: failed to parse the product catalog: %v", err)
return nil
}
return cat.Products
}
func (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) { func (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) {
return &pb.ListProductsResponse{Products: catalog}, nil return &pb.ListProductsResponse{Products: p.catalog()}, nil
} }
func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) { func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) {
for _, p := range catalog { var found *pb.Product
if req.Id == p.Id { for i := 0; i < len(p.catalog()); i++ {
return p, nil if req.Id == p.catalog()[i].Id {
found = p.catalog()[i]
} }
} }
return nil, status.Errorf(codes.NotFound, "no product with ID %s", req.Id) if found == nil {
return nil, status.Errorf(codes.NotFound, "no product with ID %s", req.Id)
}
return found, nil
} }
func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) { func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) {
// Intepret query as a substring match in name or description. // Intepret query as a substring match in name or description.
var ps []*pb.Product var ps []*pb.Product
for _, p := range catalog { for _, p := range p.catalog() {
if strings.Contains(strings.ToLower(p.Name), strings.ToLower(req.Query)) || if strings.Contains(strings.ToLower(p.Name), strings.ToLower(req.Query)) ||
strings.Contains(strings.ToLower(p.Description), strings.ToLower(req.Query)) { strings.Contains(strings.ToLower(p.Description), strings.ToLower(req.Query)) {
ps = append(ps, p) ps = append(ps, p)