mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-09-23 07:33:34 +08:00
use stopChan to close previous filer peer meta subscription instances
This commit is contained in:
@@ -21,13 +21,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MetaAggregator struct {
|
type MetaAggregator struct {
|
||||||
filer *Filer
|
filer *Filer
|
||||||
self pb.ServerAddress
|
self pb.ServerAddress
|
||||||
isLeader bool
|
isLeader bool
|
||||||
grpcDialOption grpc.DialOption
|
grpcDialOption grpc.DialOption
|
||||||
MetaLogBuffer *log_buffer.LogBuffer
|
MetaLogBuffer *log_buffer.LogBuffer
|
||||||
peerStatues map[pb.ServerAddress]int
|
peerChans map[pb.ServerAddress]chan struct{}
|
||||||
peerStatuesLock sync.Mutex
|
peerChansLock sync.Mutex
|
||||||
// notifying clients
|
// notifying clients
|
||||||
ListenersLock sync.Mutex
|
ListenersLock sync.Mutex
|
||||||
ListenersCond *sync.Cond
|
ListenersCond *sync.Cond
|
||||||
@@ -40,7 +40,7 @@ func NewMetaAggregator(filer *Filer, self pb.ServerAddress, grpcDialOption grpc.
|
|||||||
filer: filer,
|
filer: filer,
|
||||||
self: self,
|
self: self,
|
||||||
grpcDialOption: grpcDialOption,
|
grpcDialOption: grpcDialOption,
|
||||||
peerStatues: make(map[pb.ServerAddress]int),
|
peerChans: make(map[pb.ServerAddress]chan struct{}),
|
||||||
}
|
}
|
||||||
t.ListenersCond = sync.NewCond(&t.ListenersLock)
|
t.ListenersCond = sync.NewCond(&t.ListenersLock)
|
||||||
t.MetaLogBuffer = log_buffer.NewLogBuffer("aggr", LogFlushInterval, nil, func() {
|
t.MetaLogBuffer = log_buffer.NewLogBuffer("aggr", LogFlushInterval, nil, func() {
|
||||||
@@ -50,51 +50,40 @@ func NewMetaAggregator(filer *Filer, self pb.ServerAddress, grpcDialOption grpc.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ma *MetaAggregator) OnPeerUpdate(update *master_pb.ClusterNodeUpdate, startFrom time.Time) {
|
func (ma *MetaAggregator) OnPeerUpdate(update *master_pb.ClusterNodeUpdate, startFrom time.Time) {
|
||||||
|
ma.peerChansLock.Lock()
|
||||||
|
defer ma.peerChansLock.Unlock()
|
||||||
|
|
||||||
address := pb.ServerAddress(update.Address)
|
address := pb.ServerAddress(update.Address)
|
||||||
if update.IsAdd {
|
if update.IsAdd {
|
||||||
// every filer should subscribe to a new filer
|
// cancel previous subscription if any
|
||||||
if ma.setActive(address, true) {
|
if prevChan, found := ma.peerChans[address]; found {
|
||||||
go ma.loopSubscribeToOneFiler(ma.filer, ma.self, address, startFrom)
|
close(prevChan)
|
||||||
}
|
}
|
||||||
|
stopChan := make(chan struct{})
|
||||||
|
ma.peerChans[address] = stopChan
|
||||||
|
go ma.loopSubscribeToOneFiler(ma.filer, ma.self, address, startFrom, stopChan)
|
||||||
} else {
|
} else {
|
||||||
ma.setActive(address, false)
|
if prevChan, found := ma.peerChans[address]; found {
|
||||||
|
close(prevChan)
|
||||||
|
delete(ma.peerChans, address)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ma *MetaAggregator) setActive(address pb.ServerAddress, isActive bool) (notDuplicated bool) {
|
func (ma *MetaAggregator) loopSubscribeToOneFiler(f *Filer, self pb.ServerAddress, peer pb.ServerAddress, startFrom time.Time, stopChan chan struct{}) {
|
||||||
ma.peerStatuesLock.Lock()
|
|
||||||
defer ma.peerStatuesLock.Unlock()
|
|
||||||
if isActive {
|
|
||||||
if _, found := ma.peerStatues[address]; found {
|
|
||||||
ma.peerStatues[address] += 1
|
|
||||||
} else {
|
|
||||||
ma.peerStatues[address] = 1
|
|
||||||
notDuplicated = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, found := ma.peerStatues[address]; found {
|
|
||||||
delete(ma.peerStatues, address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (ma *MetaAggregator) isActive(address pb.ServerAddress) (isActive bool) {
|
|
||||||
ma.peerStatuesLock.Lock()
|
|
||||||
defer ma.peerStatuesLock.Unlock()
|
|
||||||
var count int
|
|
||||||
count, isActive = ma.peerStatues[address]
|
|
||||||
return count > 0 && isActive
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ma *MetaAggregator) loopSubscribeToOneFiler(f *Filer, self pb.ServerAddress, peer pb.ServerAddress, startFrom time.Time) {
|
|
||||||
lastTsNs := startFrom.UnixNano()
|
lastTsNs := startFrom.UnixNano()
|
||||||
for {
|
for {
|
||||||
glog.V(0).Infof("loopSubscribeToOneFiler read %s start from %v %d", peer, time.Unix(0, lastTsNs), lastTsNs)
|
glog.V(0).Infof("loopSubscribeToOneFiler read %s start from %v %d", peer, time.Unix(0, lastTsNs), lastTsNs)
|
||||||
nextLastTsNs, err := ma.doSubscribeToOneFiler(f, self, peer, lastTsNs)
|
nextLastTsNs, err := ma.doSubscribeToOneFiler(f, self, peer, lastTsNs)
|
||||||
if !ma.isActive(peer) {
|
|
||||||
glog.V(0).Infof("stop subscribing remote %s meta change", peer)
|
// check stopChan to see if we should stop
|
||||||
|
select {
|
||||||
|
case <-stopChan:
|
||||||
|
glog.V(0).Infof("stop subscribing peer %s meta change", peer)
|
||||||
return
|
return
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errLvl := glog.Level(0)
|
errLvl := glog.Level(0)
|
||||||
if strings.Contains(err.Error(), "duplicated local subscription detected") {
|
if strings.Contains(err.Error(), "duplicated local subscription detected") {
|
||||||
|
Reference in New Issue
Block a user