181 lines
3.4 KiB
Go
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{}
|
|
}
|