mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-10-15 20:06:19 +08:00
channel based visitor pattern
This commit is contained in:
@@ -97,18 +97,9 @@ func (m *Mapper) remove(machine *Machine) {
|
|||||||
foundIndex = index
|
foundIndex = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.vid2machines[v.Id] = deleteFromSlice(foundIndex,m.vid2machines[v.Id])
|
m.vid2machines[v.Id] = append(m.vid2machines[v.Id][:foundIndex], m.vid2machines[v.Id][foundIndex+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func deleteFromSlice(i int, slice []*Machine) []*Machine{
|
|
||||||
switch i {
|
|
||||||
case -1://do nothing
|
|
||||||
case 0: slice = slice[1:]
|
|
||||||
case len(slice)-1: slice = slice[:len(slice)-1]
|
|
||||||
default: slice = append(slice[:i], slice[i+1:]...)
|
|
||||||
}
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Mapper) StartRefreshWritableVolumes() {
|
func (m *Mapper) StartRefreshWritableVolumes() {
|
||||||
go func() {
|
go func() {
|
||||||
|
@@ -12,6 +12,7 @@ type DataNode struct {
|
|||||||
Port int
|
Port int
|
||||||
PublicUrl string
|
PublicUrl string
|
||||||
LastSeen int64 // unix time in seconds
|
LastSeen int64 // unix time in seconds
|
||||||
|
Dead bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDataNode(id string) *DataNode {
|
func NewDataNode(id string) *DataNode {
|
||||||
@@ -30,8 +31,8 @@ func (dn *DataNode) AddOrUpdateVolume(v *storage.VolumeInfo) {
|
|||||||
dn.volumes[v.Id] = v
|
dn.volumes[v.Id] = v
|
||||||
dn.UpAdjustActiveVolumeCountDelta(1)
|
dn.UpAdjustActiveVolumeCountDelta(1)
|
||||||
dn.UpAdjustMaxVolumeId(v.Id)
|
dn.UpAdjustMaxVolumeId(v.Id)
|
||||||
}else{
|
} else {
|
||||||
dn.volumes[v.Id] = v
|
dn.volumes[v.Id] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (dn *DataNode) GetTopology() *Topology {
|
func (dn *DataNode) GetTopology() *Topology {
|
||||||
|
@@ -20,7 +20,7 @@ type Node interface {
|
|||||||
setParent(Node)
|
setParent(Node)
|
||||||
LinkChildNode(node Node)
|
LinkChildNode(node Node)
|
||||||
UnlinkChildNode(nodeId NodeId)
|
UnlinkChildNode(nodeId NodeId)
|
||||||
CollectWritableVolumes(freshThreshHold int64, volumeSizeLimit uint64) []storage.VolumeId
|
CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64)
|
||||||
|
|
||||||
IsDataNode() bool
|
IsDataNode() bool
|
||||||
Children() map[NodeId]Node
|
Children() map[NodeId]Node
|
||||||
@@ -146,25 +146,34 @@ func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NodeImpl) CollectWritableVolumes(freshThreshHold int64, volumeSizeLimit uint64) []storage.VolumeId {
|
func (n *NodeImpl) CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64) {
|
||||||
var ret []storage.VolumeId
|
|
||||||
if n.IsRack() {
|
if n.IsRack() {
|
||||||
for _, c := range n.Children() {
|
for _, c := range n.Children() {
|
||||||
dn := c.(*DataNode) //can not cast n to DataNode
|
dn := c.(*DataNode) //can not cast n to DataNode
|
||||||
if dn.LastSeen > freshThreshHold {
|
if dn.LastSeen > freshThreshHold {
|
||||||
continue
|
if !dn.Dead {
|
||||||
|
dn.Dead = true
|
||||||
|
n.GetTopology().chanDeadDataNodes <- dn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, v := range dn.volumes {
|
for _, v := range dn.volumes {
|
||||||
if uint64(v.Size) < volumeSizeLimit {
|
if uint64(v.Size) < volumeSizeLimit {
|
||||||
ret = append(ret, v.Id)
|
n.GetTopology().chanFullVolumes <- v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, c := range n.Children() {
|
for _, c := range n.Children() {
|
||||||
ret = append(ret, c.CollectWritableVolumes(freshThreshHold, volumeSizeLimit)...)
|
c.CollectDeadNodeAndFullVolumes(freshThreshHold, volumeSizeLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret
|
|
||||||
|
func (n *NodeImpl) GetTopology() *Topology{
|
||||||
|
var p Node
|
||||||
|
p = n
|
||||||
|
for p.Parent() != nil {
|
||||||
|
p = p.Parent()
|
||||||
|
}
|
||||||
|
return p.(*Topology)
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,10 @@ func (r *Rack) GetOrCreateDataNode(ip string, port int, publicUrl string, maxVol
|
|||||||
dn := c.(*DataNode)
|
dn := c.(*DataNode)
|
||||||
if dn.MatchLocation(ip, port) {
|
if dn.MatchLocation(ip, port) {
|
||||||
dn.LastSeen = time.Now().Unix()
|
dn.LastSeen = time.Now().Unix()
|
||||||
|
if dn.Dead {
|
||||||
|
dn.Dead = false
|
||||||
|
r.GetTopology().chanRecoveredDataNodes <- dn
|
||||||
|
}
|
||||||
dn.UpAdjustMaxVolumeCountDelta(maxVolumeCount - dn.maxVolumeCount)
|
dn.UpAdjustMaxVolumeCountDelta(maxVolumeCount - dn.maxVolumeCount)
|
||||||
return dn
|
return dn
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,12 @@ type Topology struct {
|
|||||||
volumeSizeLimit uint64
|
volumeSizeLimit uint64
|
||||||
|
|
||||||
sequence sequence.Sequencer
|
sequence sequence.Sequencer
|
||||||
|
|
||||||
|
chanDeadDataNodes chan *DataNode
|
||||||
|
chanRecoveredDataNodes chan *DataNode
|
||||||
|
chanFullVolumes chan *storage.VolumeInfo
|
||||||
|
chanIncomplemteVolumes chan *storage.VolumeInfo
|
||||||
|
chanRecoveredVolumes chan *storage.VolumeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTopology(id string, dirname string, filename string, volumeSizeLimit uint64, pulse int) *Topology {
|
func NewTopology(id string, dirname string, filename string, volumeSizeLimit uint64, pulse int) *Topology {
|
||||||
@@ -31,6 +37,11 @@ func NewTopology(id string, dirname string, filename string, volumeSizeLimit uin
|
|||||||
t.pulse = int64(pulse)
|
t.pulse = int64(pulse)
|
||||||
t.volumeSizeLimit = volumeSizeLimit
|
t.volumeSizeLimit = volumeSizeLimit
|
||||||
t.sequence = sequence.NewSequencer(dirname, filename)
|
t.sequence = sequence.NewSequencer(dirname, filename)
|
||||||
|
t.chanDeadDataNodes = make(chan *DataNode)
|
||||||
|
t.chanRecoveredDataNodes = make(chan *DataNode)
|
||||||
|
t.chanFullVolumes = make(chan *storage.VolumeInfo)
|
||||||
|
t.chanIncomplemteVolumes = make(chan *storage.VolumeInfo)
|
||||||
|
t.chanRecoveredVolumes = make(chan *storage.VolumeInfo)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +106,12 @@ func (t *Topology) RegisterVolumes(volumeInfos []storage.VolumeInfo, ip string,
|
|||||||
t.RegisterVolumeLayout(&v, dn)
|
t.RegisterVolumeLayout(&v, dn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (t *Topology) SetVolumeReadOnly(volumeInfo *storage.VolumeInfo) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
func (t *Topology) UnRegisterDataNode(dn *DataNode) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Topology) GetOrCreateDataCenter(ip string) *DataCenter {
|
func (t *Topology) GetOrCreateDataCenter(ip string) *DataCenter {
|
||||||
for _, c := range t.Children() {
|
for _, c := range t.Children() {
|
||||||
@@ -128,17 +145,24 @@ func (t *Topology) ToMap() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Topology) StartRefreshWritableVolumes() {
|
func (t *Topology) StartRefreshWritableVolumes() {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
t.refreshWritableVolumes()
|
freshThreshHold := time.Now().Unix() - 3*t.pulse //5 times of sleep interval
|
||||||
time.Sleep(time.Duration(float32(t.pulse*1e3)*(1+rand.Float32())) * time.Millisecond)
|
t.CollectDeadNodeAndFullVolumes(freshThreshHold, t.volumeSizeLimit)
|
||||||
}
|
time.Sleep(time.Duration(float32(t.pulse*1e3)*(1+rand.Float32())) * time.Millisecond)
|
||||||
}()
|
}
|
||||||
}
|
}()
|
||||||
|
go func() {
|
||||||
func (t *Topology) refreshWritableVolumes() {
|
for {
|
||||||
freshThreshHold := time.Now().Unix() - 3*t.pulse //5 times of sleep interval
|
select {
|
||||||
//setting Writers, copy-on-write because of possible updating, this needs some future work!
|
case <-t.chanIncomplemteVolumes:
|
||||||
t.CollectWritableVolumes(freshThreshHold, t.volumeSizeLimit)
|
case <-t.chanRecoveredVolumes:
|
||||||
//TODO: collect writable columes for each replication type
|
case fv := <-t.chanFullVolumes:
|
||||||
|
t.SetVolumeReadOnly(fv)
|
||||||
|
case <-t.chanRecoveredDataNodes:
|
||||||
|
case dn := <-t.chanDeadDataNodes:
|
||||||
|
t.UnRegisterDataNode(dn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user