You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/app/demo/dispatch/datamanager/data.go

128 lines
3.0 KiB
Go

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package datamanager
import (
"sync"
"time"
"github.com/q191201771/naza/pkg/nazalog"
)
type DataManagerMemory struct {
serverTimeoutSec int
mutex sync.Mutex
serverID2pubStreams map[string]map[string]struct{}
serverID2AliveTS map[string]int64
}
func NewDataManagerMemory(serverTimeoutSec int) *DataManagerMemory {
d := &DataManagerMemory{
serverTimeoutSec: serverTimeoutSec,
serverID2pubStreams: make(map[string]map[string]struct{}),
serverID2AliveTS: make(map[string]int64),
}
// TODO chef: release goroutine
go func() {
var count int
for {
time.Sleep(1 * time.Second)
count++
now := time.Now().Unix()
d.mutex.Lock()
// 清除长时间没有update报活的节点
for serverID, ts := range d.serverID2AliveTS {
if now > ts && now-ts > int64(d.serverTimeoutSec)*1000 {
nazalog.Warnf("server timeout. serverID=%s", serverID)
delete(d.serverID2pubStreams, serverID)
}
}
// 定时打印数据日志
if count%60 == 0 {
nazalog.Infof("data info. %+v", d.serverID2pubStreams)
}
d.mutex.Unlock()
}
}()
return d
}
func (d *DataManagerMemory) AddPub(streamName, serverID string) {
d.mutex.Lock()
defer d.mutex.Unlock()
pss, _ := d.serverID2pubStreams[serverID]
if pss == nil {
pss = make(map[string]struct{})
}
pss[streamName] = struct{}{}
}
func (d *DataManagerMemory) DelPub(streamName, serverID string) {
d.mutex.Lock()
defer d.mutex.Unlock()
actualServerID, _ := d.queryPub(streamName)
if actualServerID != serverID {
return
}
delete(d.serverID2pubStreams[serverID], streamName)
}
func (d *DataManagerMemory) QueryPub(streamName string) (serverID string, exist bool) {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.queryPub(streamName)
}
func (d *DataManagerMemory) UpdatePub(serverID string, streamNameList []string) {
// 3. server超时去掉所有上面所有的pub
d.mutex.Lock()
defer d.mutex.Unlock()
d.markAlive(serverID)
// 更新serverID对应的stream列表
pss := make(map[string]struct{})
for _, s := range streamNameList {
pss[s] = struct{}{}
}
cpss := d.serverID2pubStreams[serverID]
d.serverID2pubStreams[serverID] = pss
// only for log
for s := range pss {
if _, exist := cpss[s]; !exist {
nazalog.Warnf("update pub, add. serverID=%s, streamName=%s", serverID, s)
}
}
for s := range cpss {
if _, exist := pss[s]; !exist {
nazalog.Warnf("update pub, del. serverID=%s, streamName=%s", serverID, s)
}
}
}
func (d *DataManagerMemory) queryPub(streamName string) (string, bool) {
for serverID, pss := range d.serverID2pubStreams {
if _, exist := pss[streamName]; exist {
return serverID, true
}
}
return "", false
}
func (d *DataManagerMemory) markAlive(serverID string) {
d.serverID2AliveTS[serverID] = time.Now().Unix()
}