package cmmanager
import (
"sync"
"ascend-common/common-utils/hwlog"
"clusterd/pkg/common/constant"
"clusterd/pkg/common/util"
"clusterd/pkg/domain/faultdomain/collector"
)
type ConfigMap[T constant.ConfigMapInterface] struct {
Data map[string]T
}
var DeviceCenterCmManager *FaultCenterCmManager[*constant.AdvanceDeviceFaultCm]
var SwitchCenterCmManager *FaultCenterCmManager[*constant.SwitchInfo]
var NodeCenterCmManager *FaultCenterCmManager[*constant.NodeInfo]
var DpuCenterCMManager *FaultCenterCmManager[*constant.DpuInfoCM]
type FaultCenterCmManager[T constant.ConfigMapInterface] struct {
mutex sync.RWMutex
cmBuffer *collector.ConfigmapCollectBuffer[T]
originalCm ConfigMap[T]
processedCm ConfigMap[T]
isChanged bool
}
func init() {
DeviceCenterCmManager = &FaultCenterCmManager[*constant.AdvanceDeviceFaultCm]{
mutex: sync.RWMutex{},
originalCm: ConfigMap[*constant.AdvanceDeviceFaultCm]{Data: make(map[string]*constant.AdvanceDeviceFaultCm)},
processedCm: ConfigMap[*constant.AdvanceDeviceFaultCm]{Data: make(map[string]*constant.AdvanceDeviceFaultCm)},
cmBuffer: collector.DeviceCmCollectBuffer,
}
SwitchCenterCmManager = &FaultCenterCmManager[*constant.SwitchInfo]{
mutex: sync.RWMutex{},
originalCm: ConfigMap[*constant.SwitchInfo]{Data: make(map[string]*constant.SwitchInfo)},
processedCm: ConfigMap[*constant.SwitchInfo]{Data: make(map[string]*constant.SwitchInfo)},
cmBuffer: collector.SwitchCmCollectBuffer,
}
NodeCenterCmManager = &FaultCenterCmManager[*constant.NodeInfo]{
mutex: sync.RWMutex{},
originalCm: ConfigMap[*constant.NodeInfo]{Data: make(map[string]*constant.NodeInfo)},
processedCm: ConfigMap[*constant.NodeInfo]{Data: make(map[string]*constant.NodeInfo)},
cmBuffer: collector.NodeCmCollectBuffer,
}
DpuCenterCMManager = &FaultCenterCmManager[*constant.DpuInfoCM]{
mutex: sync.RWMutex{},
originalCm: ConfigMap[*constant.DpuInfoCM]{Data: make(map[string]*constant.DpuInfoCM)},
processedCm: ConfigMap[*constant.DpuInfoCM]{Data: make(map[string]*constant.DpuInfoCM)},
cmBuffer: collector.DpuCMCollectBuffer,
}
}
func (manager *FaultCenterCmManager[T]) GetOriginalCm() ConfigMap[T] {
manager.mutex.RLock()
defer manager.mutex.RUnlock()
return manager.originalCm.deepCopy()
}
func (manager *FaultCenterCmManager[T]) SetProcessedCm(cm ConfigMap[T]) bool {
manager.mutex.Lock()
defer manager.mutex.Unlock()
if manager.processedCm.equal(cm) {
manager.isChanged = false
return false
}
manager.isChanged = true
manager.processedCm = cm.deepCopy()
return true
}
func (manager *FaultCenterCmManager[T]) GetProcessedCm() ConfigMap[T] {
manager.mutex.RLock()
defer manager.mutex.RUnlock()
return manager.processedCm.deepCopy()
}
func (manager *FaultCenterCmManager[T]) updateOriginalCm(newInfo T, isAdd bool) {
manager.mutex.Lock()
defer manager.mutex.Unlock()
manager.originalCm.updateCmInfo(newInfo, isAdd)
}
func (manager *FaultCenterCmManager[T]) UpdateBatchOriginalCm() []constant.InformerCmItem[T] {
informerCms := manager.cmBuffer.Pop()
for _, cm := range informerCms {
manager.updateOriginalCm(cm.Data, cm.IsAdd)
}
return informerCms
}
func (manager *FaultCenterCmManager[T]) IsChanged() bool {
return manager.isChanged
}
func (cm *ConfigMap[T]) deepCopy() ConfigMap[T] {
result := new(map[string]T)
err := util.DeepCopy(result, cm.Data)
if err != nil {
hwlog.RunLog.Errorf("deepCopy deviceInfoCm failed: %v", err)
return ConfigMap[T]{}
}
return ConfigMap[T]{Data: *result}
}
func (cm *ConfigMap[T]) updateCmInfo(newInfo T, isAdd bool) {
if isAdd {
if cm.Data == nil {
cm.Data = make(map[string]T)
}
length := len(cm.Data)
if length > constant.MaxSupportNodeNum {
hwlog.RunLog.Errorf("updateCmInfo %s failed, exceed length", util.ObjToString(newInfo))
return
}
newInfo.UpdateFaultReceiveTime(cm.Data[newInfo.GetCmName()])
cm.Data[newInfo.GetCmName()] = newInfo
hwlog.RunLog.Debugf("add DeviceInfo: %s", util.ObjToString(newInfo))
return
}
delete(cm.Data, newInfo.GetCmName())
}
func (cm *ConfigMap[T]) equal(other ConfigMap[T]) bool {
if len(cm.Data) != len(other.Data) {
return false
}
for cmName, info := range cm.Data {
otherInfo, found := other.Data[cmName]
if !found {
return false
}
if !info.IsSame(otherInfo) {
return false
}
}
return true
}