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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 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()
}