Package Status:

- fix listmandatory: transform into sync.map to prevent race detection
This commit is contained in:
nabbar
2023-08-06 14:30:52 +02:00
parent 212cfdc0cf
commit eb5c4219d3
3 changed files with 167 additions and 90 deletions

View File

@@ -42,16 +42,16 @@ const (
keyConfigMandatory = "cfgMandatory"
)
type Config struct {
ReturnCode map[monsts.Status]int
MandatoryComponent stslmd.ListMandatory
}
type Mandatory struct {
Mode stsctr.Mode
Keys []string
}
type Config struct {
ReturnCode map[monsts.Status]int
MandatoryComponent []Mandatory
}
func (o Config) Validate() error {
var e = ErrorValidatorError.Error(nil)
@@ -75,7 +75,6 @@ func (o Config) Validate() error {
func (o *sts) SetConfig(cfg Config) {
if len(cfg.ReturnCode) < 1 {
var def = make(map[monsts.Status]int, 0)
def[monsts.KO] = http.StatusInternalServerError
def[monsts.Warn] = http.StatusMultiStatus
@@ -86,11 +85,18 @@ func (o *sts) SetConfig(cfg Config) {
o.x.Store(keyConfigReturnCode, cfg.ReturnCode)
}
if len(cfg.MandatoryComponent) < 1 {
o.x.Store(keyConfigMandatory, make([]string, 0))
} else {
o.x.Store(keyConfigMandatory, cfg.MandatoryComponent)
var lst = stslmd.New()
if len(cfg.MandatoryComponent) > 0 {
for _, i := range cfg.MandatoryComponent {
var m = stsmdt.New()
m.SetMode(i.Mode)
m.KeyAdd(i.Keys...)
lst.Add(m)
}
}
o.x.Store(keyConfigMandatory, lst)
}
func (o *sts) cfgGetReturnCode(s monsts.Status) int {
@@ -116,7 +122,7 @@ func (o *sts) cfgGetMandatory() stslmd.ListMandatory {
}
func (o *sts) cfgGetMode(key string) stsctr.Mode {
if l := o.cfgGetMandatory(); len(l) < 1 {
if l := o.cfgGetMandatory(); l == nil {
return stsctr.Ignore
} else {
return l.GetMode(key)
@@ -124,7 +130,7 @@ func (o *sts) cfgGetMode(key string) stsctr.Mode {
}
func (o *sts) cfgGetOne(key string) []string {
if l := o.cfgGetMandatory(); len(l) < 1 {
if l := o.cfgGetMandatory(); l == nil {
return make([]string, 0)
} else {
var r []string

View File

@@ -26,12 +26,34 @@
package listmandatory
import stsmdt "github.com/nabbar/golib/status/mandatory"
import (
"sync"
"sync/atomic"
type ListMandatory []stsmdt.Mandatory
stsctr "github.com/nabbar/golib/status/control"
stsmdt "github.com/nabbar/golib/status/mandatory"
)
type ListMandatory interface {
Len() int
Walk(fct func(m stsmdt.Mandatory) bool)
Add(m ...stsmdt.Mandatory)
Del(m stsmdt.Mandatory)
GetMode(key string) stsctr.Mode
SetMode(key string, mod stsctr.Mode)
}
func New(m ...stsmdt.Mandatory) ListMandatory {
res := make([]stsmdt.Mandatory, 0)
copy(res, m)
return res
var o = &model{
l: sync.Map{},
k: new(atomic.Int32),
}
o.k.Store(0)
for _, i := range m {
o.l.Store(o.inc(), i)
}
return o
}

View File

@@ -27,100 +27,149 @@
package listmandatory
import (
"sort"
"sync"
"sync/atomic"
stsctr "github.com/nabbar/golib/status/control"
stsmdt "github.com/nabbar/golib/status/mandatory"
"golang.org/x/exp/slices"
)
func (l *ListMandatory) Walk(fct func(m stsmdt.Mandatory) bool) {
if l == nil {
return
} else if len(*l) < 1 {
return
}
type model struct {
l sync.Map
k *atomic.Int32
}
var (
k bool
m stsmdt.Mandatory
n = *l
)
func (o *model) inc() int32 {
i := o.k.Load()
i++
o.k.Store(i)
return i
}
for i := range n {
m = n[i]
k = fct(m)
n[i] = m
func (o *model) Len() int {
var l int
if !k {
break
o.l.Range(func(key, value any) bool {
var k bool
if _, k = key.(int32); !k {
o.l.Delete(key)
return true
} else if _, k = value.(stsmdt.Mandatory); !k {
o.l.Delete(key)
return true
}
}
*l = n
l++
return true
})
return l
}
func (l *ListMandatory) Add(m ...stsmdt.Mandatory) {
if l == nil {
return
}
func (o *model) Walk(fct func(m stsmdt.Mandatory) bool) {
o.l.Range(func(key, value any) bool {
var (
k bool
v stsmdt.Mandatory
)
var n = *l
if len(n) < 1 {
n = make([]stsmdt.Mandatory, 0)
}
*l = append(n, m...)
}
func (l *ListMandatory) Del(m stsmdt.Mandatory) {
if l == nil {
return
}
var (
n = *l
r = make([]stsmdt.Mandatory, 0)
)
if len(n) < 1 {
*l = make([]stsmdt.Mandatory, 0)
return
}
for i := range n {
if n[i] != m {
r = append(r, n[i])
if _, k = key.(int32); !k {
o.l.Delete(key)
return true
} else if v, k = value.(stsmdt.Mandatory); !k {
o.l.Delete(key)
return true
} else {
k = fct(v)
o.l.Store(k, v)
return k
}
}
*l = r
})
}
func (l ListMandatory) GetMode(key string) stsctr.Mode {
if len(l) < 1 {
return stsctr.Ignore
func (o *model) Add(m ...stsmdt.Mandatory) {
for _, v := range m {
o.l.Store(o.inc(), v)
}
}
for i := range l {
if l[i].KeyHas(key) {
return l[i].GetMode()
func (o *model) Del(m stsmdt.Mandatory) {
o.l.Range(func(key, value any) bool {
var (
k bool
v stsmdt.Mandatory
)
if _, k = key.(int32); !k {
o.l.Delete(key)
return true
} else if v, k = value.(stsmdt.Mandatory); !k {
o.l.Delete(key)
return true
} else {
u := v.KeyList()
sort.Strings(u)
n := m.KeyList()
sort.Strings(n)
if slices.Compare(u, n) != 0 {
return true
}
o.l.Delete(key)
return true
}
}
return stsctr.Ignore
})
}
func (l *ListMandatory) SetMode(key string, mod stsctr.Mode) {
if len(*l) < 1 {
return
}
func (o *model) GetMode(key string) stsctr.Mode {
var res = stsctr.Ignore
var n = *l
o.l.Range(func(ref, value any) bool {
var (
k bool
v stsmdt.Mandatory
)
for i := range n {
if n[i].KeyHas(key) {
n[i].SetMode(mod)
*l = n
return
if _, k = ref.(int32); !k {
o.l.Delete(ref)
return true
} else if v, k = value.(stsmdt.Mandatory); !k {
o.l.Delete(ref)
return true
} else if v.KeyHas(key) {
res = v.GetMode()
return false
} else {
return true
}
}
})
return res
}
func (o *model) SetMode(key string, mod stsctr.Mode) {
o.l.Range(func(ref, value any) bool {
var (
k bool
v stsmdt.Mandatory
)
if _, k = ref.(int32); !k {
o.l.Delete(ref)
return true
} else if v, k = value.(stsmdt.Mandatory); !k {
o.l.Delete(ref)
return true
} else if v.KeyHas(key) {
v.SetMode(mod)
return false
} else {
return true
}
})
}