fix(CurrentRecipePointer): 🐛 Fix "set from cache" bug

Add validator to check if current recipe pointer is set-able or not
This commit is contained in:
pakintada@gmail.com 2024-04-08 16:47:59 +07:00
parent 64a98cea51
commit 4219c1cb43
3 changed files with 90 additions and 16 deletions

View file

@ -338,6 +338,9 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
return d.CurrentRecipe[countryID] return d.CurrentRecipe[countryID]
} }
// add validate flag
needValidate := false
// do check if match the current pointer // do check if match the current pointer
if d.CurrentFile[countryID] == filename { if d.CurrentFile[countryID] == filename {
d.taoLogger.Log.Debug("GetRecipe", d.taoLogger.Log.Debug("GetRecipe",
@ -352,11 +355,13 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
// get requested version // get requested version
requestedConfig, _ := strconv.Atoi(strings.Split(strings.Split(filename, "_")[1], ".")[0]) requestedConfig, _ := strconv.Atoi(strings.Split(strings.Split(filename, "_")[1], ".")[0])
if currentConfig != requestedConfig { if currentConfig != requestedConfig {
// TODO: from `/dashboard`, this already checked the version if matched,
d.taoLogger.Log.Debug("GetRecipe", zap.Any("ActualFileNotMatch", "Skip this!")) d.taoLogger.Log.Debug("GetRecipe", zap.Any("ActualFileNotMatch", "Skip this!"))
needValidate = true
} else { } else {
// detect patches, return original // detect patches, return original
var cached_original_recipe models.Recipe var cached_original_recipe *models.Recipe = &models.Recipe{}
err := d.redisClient.GetKeyTo(filename, &cached_original_recipe) err := d.redisClient.GetKeyTo(filename, &cached_original_recipe)
// for index, v := range cached_original_recipe.Recipe01 { // for index, v := range cached_original_recipe.Recipe01 {
@ -365,7 +370,7 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
if err == nil && d.redisClient.HealthCheck() == nil { if err == nil && d.redisClient.HealthCheck() == nil {
d.taoLogger.Log.Debug("GetRecipe.NoReturnUpdated", zap.Any("target", filename)) d.taoLogger.Log.Debug("GetRecipe.NoReturnUpdated", zap.Any("target", filename))
return &cached_original_recipe return cached_original_recipe
} }
// if equal, OK // if equal, OK
@ -390,12 +395,12 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
// detect patches, return original // detect patches, return original
var cached_original_recipe models.Recipe var cached_original_recipe *models.Recipe = &models.Recipe{}
err := d.redisClient.GetKeyTo(filename, &cached_original_recipe) err := d.redisClient.GetKeyTo(filename, &cached_original_recipe)
if err == nil && d.redisClient.HealthCheck() == nil { if err == nil && d.redisClient.HealthCheck() == nil {
d.taoLogger.Log.Debug("GetRecipe.NoReturnUpdated", zap.Any("target", filename)) d.taoLogger.Log.Debug("GetRecipe.NoReturnUpdated", zap.Any("target", filename))
return &cached_original_recipe return cached_original_recipe
} }
d.taoLogger.Log.Debug("GetRecipe.ReturnDefault", zap.Any("error_cache_recipe", err)) d.taoLogger.Log.Debug("GetRecipe.ReturnDefault", zap.Any("error_cache_recipe", err))
@ -408,9 +413,30 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
// change current version and read new recipe // change current version and read new recipe
if filename == "default" { if filename == "default" {
filename = d.CurrentFile[countryID] // use redis cache
if d.redisClient.HealthCheck() == nil {
d.taoLogger.Log.Debug("GetRecipe", zap.Any("RedisOffline", "return default recipe"))
// var defaultFileName string
d.taoLogger.Log.Debug("GetRcipe.TryGetDefaultFromRedis", zap.Any("ByCountry", countryID))
var cached_default_recipe *models.Recipe = &models.Recipe{}
err := d.redisClient.GetKeyTo(countryID, cached_default_recipe)
if err != nil {
filename = d.CurrentFile[countryID]
d.taoLogger.Log.Debug("GetRecipe.ReplaceDefaultCase2", zap.Any("RedisGetKeyFail+getFromServerMem", filename), zap.Any("Error", err))
} else {
// filename = defaultFileName
d.taoLogger.Log.Debug("GetRecipe.ReplaceDefaultCase3", zap.Any("Case3+RedisOK,do check if matched", filename))
return cached_default_recipe
}
} else {
filename = d.CurrentFile[countryID]
d.taoLogger.Log.Debug("GetRecipe.ReplaceDefaultCase1", zap.Any("RedisOffline+getFromServerMem", filename))
}
} }
d.taoLogger.Log.Debug("GetRecipe.ReplaceDefault", zap.Any("Filename", filename), zap.Any("Conflict", needValidate))
// var recipe *models.Recipe = &models.Recipe{} // var recipe *models.Recipe = &models.Recipe{}
// do check if redis contains the recipe // do check if redis contains the recipe
@ -457,7 +483,12 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
return_recipe = cached_recipe return_recipe = cached_recipe
} else { } else {
d.taoLogger.Log.Debug("GetRecipeCached", zap.Any("cached_recipe", "no")) d.taoLogger.Log.Debug("GetRecipeCached", zap.Any("cached_recipe", "no"))
// d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
return_recipe = recipe return_recipe = recipe
} }
@ -659,7 +690,11 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string)
d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("version", recipe.MachineSetting.ConfigNumber)) d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("version", recipe.MachineSetting.ConfigNumber))
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
// save to map // save to map
if len(d.recipeMap) > 5 { // limit keep in memory 5 version if len(d.recipeMap) > 5 { // limit keep in memory 5 version
@ -879,7 +914,11 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS
// d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("recipe", recipe.MaterialSetting)) // d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("recipe", recipe.MaterialSetting))
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
// save to map // save to map
if len(d.recipeMap) > 5 { // limit keep in memory 5 version if len(d.recipeMap) > 5 { // limit keep in memory 5 version
@ -925,7 +964,11 @@ func (d *Data) GetAllToppingGroups(countryID, filename string) []models.ToppingG
} }
recipe := d.GetRecipe(countryID, filename) recipe := d.GetRecipe(countryID, filename)
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
if len(d.recipeMap) > 5 { // limit keep in memory 5 version if len(d.recipeMap) > 5 { // limit keep in memory 5 version
// remove oldest version // remove oldest version
@ -1015,7 +1058,11 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model
// return d.CurrentRecipe[countryID].MaterialCode // return d.CurrentRecipe[countryID].MaterialCode
// } // }
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
// save to map // save to map
if len(d.recipeMap) > 5 { // limit keep in memory 5 version if len(d.recipeMap) > 5 { // limit keep in memory 5 version
@ -1069,15 +1116,19 @@ func (d *Data) GetToppings(countryID, filename string) models.Topping {
return recipe.Recipe[countryID].Topping return recipe.Recipe[countryID].Topping
} }
if filename == "default" { // if filename == "default" {
filename = d.CurrentFile[countryID] // filename = d.CurrentFile[countryID]
} // }
// d.CurrentFile[countryID] = filename // d.CurrentFile[countryID] = filename
// d.CurrentCountryID[countryID] = countryID // d.CurrentCountryID[countryID] = countryID
recipe := d.GetRecipe(countryID, filename) recipe := d.GetRecipe(countryID, filename)
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
return recipe.Topping return recipe.Topping
} }
@ -1346,7 +1397,11 @@ func (d *Data) SortRecipe(countryID, filename string, sort_by string, ascending
} }
fmt.Println("set to server mem") fmt.Println("set to server mem")
d.CurrentRecipe[countryID] = recipe // TODO: handle country and recipe not match
isFound, index := d.ValidateUpdateCurrentRecipePointer(countryID, filename)
if isFound && index != -1 {
d.CurrentRecipe[countryID] = recipe
}
} }
@ -1511,3 +1566,18 @@ func (d *Data) finalizedVersion(country string, sourceRecipe *models.Recipe) (st
return updatedFilename, nil return updatedFilename, nil
} }
func (d *Data) ValidateUpdateCurrentRecipePointer(countryID, filename string) (bool, int) {
found := false
idx := -1
for index, file := range d.AllRecipeFiles[countryID] {
if file.Name == filename {
found = true
idx = index
}
}
d.taoLogger.Log.Debug("ValidateUpdateCurrentRecipePointer", zap.Any("args", []string{countryID, filename}), zap.Any("pass", found))
return found, idx
}

View file

@ -28,6 +28,8 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
const VERSION = "1.0.1b"
type Server struct { type Server struct {
server *http.Server server *http.Server
data *data.Data data *data.Data
@ -63,6 +65,7 @@ func (s *Server) Run() error {
s.createHandler() s.createHandler()
// log.Printf("Server running on %s", s.server.Addr) // log.Printf("Server running on %s", s.server.Addr)
s.taoLogger.Log.Info("Server running", zap.String("addr", s.server.Addr)) s.taoLogger.Log.Info("Server running", zap.String("addr", s.server.Addr))
s.taoLogger.Log.Info("Version", zap.String("version", VERSION))
defer func(Log *zap.Logger) { defer func(Log *zap.Logger) {
err := Log.Sync() err := Log.Sync()

View file

@ -3,6 +3,7 @@ package logger
import ( import (
"os" "os"
"recipe-manager/config" "recipe-manager/config"
"time"
"github.com/natefinch/lumberjack" "github.com/natefinch/lumberjack"
"go.uber.org/zap" "go.uber.org/zap"
@ -30,7 +31,7 @@ func (tl *TaoLogger) initConfig() *zap.Logger {
MessageKey: "message", MessageKey: "message",
StacktraceKey: "error", StacktraceKey: "error",
EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder, EncodeTime: zapcore.TimeEncoderOfLayout(time.DateTime),
}), zapcore.AddSync(&lumberjack.Logger{ }), zapcore.AddSync(&lumberjack.Logger{
Filename: "services/logger/serverlog.log", Filename: "services/logger/serverlog.log",
MaxSize: 5, // megabytes MaxSize: 5, // megabytes