package f5 import ( "q5" "os" "time" "sync" "errors" "gorm.io/gorm" ) const ( ONLINE_ENV = 0 TEST_ENV = iota DEV_ENV = iota ) var serverEnv int32 var globalLock sync.Mutex var globalLockHash map[string]*sync.Mutex func IsTestEnv() bool { return serverEnv == TEST_ENV } func IsOnlineEnv() bool { return serverEnv == ONLINE_ENV } func IsDevEnv() bool { return serverEnv == DEV_ENV } func New[T any](cb func(*T)) *T { obj := new(T) cb(obj) return obj } func ExtractRegisterTimeFromSessionId(sessionId string) int32 { strList := q5.StrSplit(sessionId, "_") if len(strList) < 4 { return 0 } return q5.ToInt32(strList[0]) } func IsOrmErrRecordNotFound(err error) bool { return errors.Is(err, gorm.ErrRecordNotFound) } func AllocLock(key string) *sync.Mutex { var l *sync.Mutex globalLock.Lock() if p, ok := globalLockHash[key]; ok { l = p } else { l = new(sync.Mutex) globalLockHash[key] = l } globalLock.Unlock() go func () { time.Sleep(time.Second * 30) globalLock.Lock() delete(globalLockHash, key) globalLock.Unlock() }() l.Lock() return l } func ReleaseLock(l *sync.Mutex) { l.Unlock() } func BatchAllocLock(keys []string) []*sync.Mutex { locks := []*sync.Mutex{} lock := sync.Mutex{} for _, key := range keys { go func () { l := AllocLock(key) lock.Lock() q5.AppendSlice(&locks, l) lock.Unlock() }() } for len(locks) < len(keys) { time.Sleep(time.Millisecond * 10) } return locks } func BatchReleaseLock(locks []*sync.Mutex) { for _, val := range locks { ReleaseLock(val) } } func init() { switch os.Getenv("SERVER_ENV") { case "TEST": serverEnv = TEST_ENV case "DEBUG": serverEnv = DEV_ENV default: serverEnv = ONLINE_ENV } globalLockHash = map[string]*sync.Mutex{} }