1
0
forked from x/icebergs
icebergs/base/mdb/lock.go
2024-09-03 07:35:53 +08:00

109 lines
2.5 KiB
Go

package mdb
import (
"time"
"sync"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/task"
)
var _lock = task.Lock{}
var _locks = map[string]*task.Lock{}
func getLock(m *ice.Message, arg ...string) *task.Lock {
key := kit.Select(m.PrefixKey(), kit.Keys(arg))
defer _lock.Lock()()
l, ok := _locks[key]
kit.If(!ok, func() { l = &task.Lock{}; _locks[key] = l })
return l
}
func Lock(m *ice.Message, arg ...string) func() {
return getLock(m, arg...).Lock()
key := kit.Select(m.PrefixKey(), kit.Keys(arg))
m.Info("what %v", key)
cb := getLock(m, arg...).Lock()
m.Info("what %v", key)
go func() {
time.Sleep(30*time.Second)
if cb == nil {
return
}
cb()
m.Warn("lock time out %v %v", key, m.FormatStack(1, 100))
}()
return func() {
cb()
cb = nil
}
}
func RLock(m *ice.Message, arg ...string) func() {
return getLock(m, arg...).RLock()
key := kit.Select(m.PrefixKey(), kit.Keys(arg))
m.Info("what %v", key)
cb := getLock(m, arg...).RLock()
m.Info("what %v", key)
go func() {
time.Sleep(30*time.Second)
if cb == nil {
return
}
cb()
m.Warn("lock time out %v %v", key, m.FormatStack(1, 100))
}()
return func() {
cb()
cb = nil
}
}
func ConfigSimple(m *ice.Message, key ...string) (res []string) {
for _, key := range key {
res = append(res, key, kit.Format(Configv(m, key)))
}
return
}
func Config(m *ice.Message, key string, arg ...Any) string {
return kit.Format(Configv(m, key, arg...))
}
func Configv(m *ice.Message, key string, arg ...Any) Any {
kit.If(len(arg) > 0, func() { Confv(m, m.PrefixKey(), kit.Keym(key), arg[0]) })
return Confv(m, m.PrefixKey(), kit.Keym(key))
}
func Confv(m *ice.Message, arg ...Any) Any {
key := kit.Select(m.PrefixKey(), kit.Format(arg[0]))
if ctx, ok := ice.Info.Index[key].(*ice.Context); ok {
key = ctx.Prefix(key)
}
if len(arg) > 2 {
defer Lock(m, key)()
} else {
defer RLock(m, key)()
}
return m.Confv(arg...)
}
func Conf(m *ice.Message, arg ...Any) string { return kit.Format(Confv(m, arg...)) }
func Confm(m *ice.Message, key string, sub Any, cbs ...Any) Map {
val := m.Confv(key, sub)
kit.If(len(cbs) > 0, func() { kit.For(val, cbs[0]) })
value, _ := val.(Map)
return value
}
var cache = sync.Map{}
func Cache(m *ice.Message, key string, add func() Any) Any {
if key = kit.Keys(m.PrefixKey(), key); add == nil {
cache.Delete(key)
return nil
} else if val, ok := cache.Load(key); ok {
return val
} else if val := add(); val != nil {
cache.Store(key, val)
return val
} else {
return nil
}
}