f5/sysutils.go
aozhiwei 1b00affd82 1
2024-07-20 22:39:16 +08:00

181 lines
3.4 KiB
Go

package f5
import (
"q5"
"os"
"time"
"sync"
"errors"
"gorm.io/gorm"
"net/http"
"github.com/gin-gonic/gin"
)
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 RspErr(c *gin.Context, errCode int32, errMsg string) {
c.JSON(http.StatusOK, gin.H{
"errcode": errCode,
"errmsg": errMsg,
})
}
func RspErr2(c *gin.Context, code int32, message string) {
c.JSON(http.StatusOK, gin.H{
"code": code,
"message": message,
})
}
func DataSetStreamPageQuery(dataSet []interface{},
pageSize int32, cursor int64,
filterCb func(interface{}) bool,
orderByCb func(interface{}, interface{}) bool,
queryCb func(*StreamPagination),
fillCb func(interface{})) {
if pageSize <= 0 {
pageSize = 1
}
if pageSize > 1000 {
pageSize = 1000
}
if cursor < 1 {
cursor = 1
}
if cursor > 10000 {
cursor = 10000
}
var dataSetCopy []*interface{}
q5.NewSlice(&dataSetCopy, 0, int32(len(dataSet)))
for _, val := range dataSet {
tmpVal := val
if filterCb(val) {
q5.AppendSlice(&dataSetCopy, &tmpVal)
}
}
q5.Sort(dataSetCopy, func(a *interface{}, b *interface{}) bool {
return orderByCb(*a, *b)
})
var pagination StreamPagination
pagination.NextCursor = cursor
if int64(pageSize) * cursor < int64(len(dataSetCopy)) {
pagination.NextCursor = cursor + 1
pagination.Remaining = 1
}
pagination.PreviousCursor = q5.Max(1, cursor - 1)
pagination.Count = int32(int64(len(dataSetCopy)) - int64(pageSize) * (cursor - 1))
if pagination.Count < 0 {
pagination.Count = 0
} else {
pagination.Count = q5.Min(pageSize, pagination.Count)
}
pagination.TotalCount = int32(len(dataSetCopy))
queryCb(&pagination)
var count int32
startIdx := int(int64(pageSize) * (cursor - 1))
for i := startIdx; i < len(dataSetCopy); i++ {
fillCb(*dataSetCopy[i])
count++
if count >= pagination.Count {
break
}
}
}
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{}
}