package system import ( "wpw-common/internal" "go.uber.org/zap" "gorm.io/gorm" ) type SystemKV struct { gorm.Model Key string Value string } type system struct { logger *zap.SugaredLogger db *gorm.DB } var Default system func (s *system) init(appCtx *internal.AppContext) { logger := appCtx.Logger.Sugar().Named("system") db, exist := appCtx.Data["db"] if !exist { logger.Fatal("system requires `db` in application context") } s.logger = logger s.db = db.(*gorm.DB) s.db.AutoMigrate(&SystemKV{}) } func (s *system) DoOnce(key string, fn func() error) (err error) { var kv SystemKV kv.Key = key tx := s.db.First(&kv) if err = tx.Error; err == gorm.ErrRecordNotFound { s.logger.Info("doOnce call", "key", key) if err = fn(); err != nil { return } tx = s.db.Create(&kv) if err = tx.Error; err != nil { return } } else if err == nil { s.logger.Infow("doOnce done", "key", key, "at", kv.CreatedAt) return } return } func Init(appCtx *internal.AppContext) { Default.init(appCtx) }