Delay in ProductCatalogService for demos
This delay is implemented as a broken feature. It can be triggered and removed via USR1/USR2.
This commit is contained in:
parent
5272a4d821
commit
ce80e8b119
2 changed files with 65 additions and 6 deletions
|
@ -3,3 +3,29 @@
|
|||
Run the following command to restore dependencies to `vendor/` directory:
|
||||
|
||||
dep ensure --vendor-only
|
||||
|
||||
## Dynamic catalog reloading / artificial delay
|
||||
|
||||
This service has a "dynamic catalog reloading" feature that is purposefully
|
||||
not well implemented. The goal of this feature is to allow you to modify the
|
||||
`products.json` file and have the changes be picked up without having to
|
||||
restart the service.
|
||||
|
||||
However, this feature is bugged: the catalog is actually reloaded on each
|
||||
request, introducing a noticeable delay in the frontend. This delay will also
|
||||
show up in profiling tools: the `parseCatalog` function will take more than 80%
|
||||
of the CPU time.
|
||||
|
||||
You can trigger this feature (and the delay) by sending a `USR1` signal and
|
||||
remove it (if needed) by sending a `USR2` signal:
|
||||
|
||||
```
|
||||
# Trigger bug
|
||||
kubectl exec \
|
||||
$(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \
|
||||
-c server -- kill -USR1 1
|
||||
# Remove bug
|
||||
kubectl exec \
|
||||
$(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \
|
||||
-c server -- kill -USR2 1
|
||||
```
|
||||
|
|
|
@ -22,7 +22,9 @@ import (
|
|||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
pb "github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice/genproto"
|
||||
|
@ -42,9 +44,12 @@ import (
|
|||
|
||||
var (
|
||||
catalogJSON []byte
|
||||
cat pb.ListProductsResponse
|
||||
log *logrus.Logger
|
||||
|
||||
port = flag.Int("port", 3550, "port to listen at")
|
||||
|
||||
reloadCatalog bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -53,6 +58,9 @@ func init() {
|
|||
log.Fatalf("failed to open product catalog json file: %v", err)
|
||||
}
|
||||
catalogJSON = c
|
||||
if err := jsonpb.Unmarshal(bytes.NewReader(catalogJSON), &cat); err != nil {
|
||||
log.Warnf("failed to parse the catalog JSON: %v", err)
|
||||
}
|
||||
log = logrus.New()
|
||||
log.Formatter = &logrus.JSONFormatter{
|
||||
FieldMap: logrus.FieldMap{
|
||||
|
@ -71,6 +79,22 @@ func main() {
|
|||
go initProfiling("productcatalogservice", "1.0.0")
|
||||
flag.Parse()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGUSR1, syscall.SIGUSR2)
|
||||
go func() {
|
||||
for {
|
||||
sig := <-sigs
|
||||
log.Printf("Received signal: %s", sig)
|
||||
if sig == syscall.SIGUSR1 {
|
||||
reloadCatalog = true
|
||||
log.Infof("Enable catalog reloading")
|
||||
} else {
|
||||
reloadCatalog = false
|
||||
log.Infof("Disable catalog reloading")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
log.Infof("starting grpc server at :%d", *port)
|
||||
run(*port)
|
||||
select {}
|
||||
|
@ -147,13 +171,22 @@ func initProfiling(service, version string) {
|
|||
type productCatalog struct{}
|
||||
|
||||
func parseCatalog() []*pb.Product {
|
||||
var cat pb.ListProductsResponse
|
||||
|
||||
if err := jsonpb.Unmarshal(bytes.NewReader(catalogJSON), &cat); err != nil {
|
||||
log.Warnf("failed to parse the catalog JSON: %v", err)
|
||||
return nil
|
||||
if reloadCatalog {
|
||||
var catalog pb.ListProductsResponse
|
||||
c, err := ioutil.ReadFile("products.json")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open product catalog json file: %v", err)
|
||||
return nil
|
||||
}
|
||||
if err := jsonpb.Unmarshal(bytes.NewReader(c), &catalog); err != nil {
|
||||
log.Warnf("failed to parse the catalog JSON: %v", err)
|
||||
return nil
|
||||
}
|
||||
log.Infof("Catalog reloaded")
|
||||
return catalog.Products
|
||||
} else {
|
||||
return cat.Products
|
||||
}
|
||||
return cat.Products
|
||||
}
|
||||
|
||||
func (p *productCatalog) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue