mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 05:57:03 +09:00
176 lines
4.4 KiB
Go
176 lines
4.4 KiB
Go
package nodeconf
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"github.com/anyproto/go-chash"
|
||
)
|
||
|
||
type NodeConf interface {
|
||
// Id returns current nodeconf id
|
||
Id() string
|
||
// Configuration returns configuration struct
|
||
Configuration() Configuration
|
||
// NodeIds returns list of peerId for given spaceId
|
||
NodeIds(spaceId string) []string
|
||
// IsResponsible checks if current account responsible for given spaceId
|
||
IsResponsible(spaceId string) bool
|
||
// FilePeers returns list of filenodes
|
||
FilePeers() []string
|
||
// ConsensusPeers returns list of consensusnodes
|
||
ConsensusPeers() []string
|
||
// CoordinatorPeers returns list of coordinator nodes
|
||
CoordinatorPeers() []string
|
||
// Please see any-ns-node repo for details
|
||
// Usually one network has only 1 naming node, but we support array of NNs
|
||
NamingNodePeers() []string
|
||
// Please see any-pp-node repo for details
|
||
PaymentProcessingNodePeers() []string
|
||
// PeerAddresses returns peer addresses by peer id
|
||
PeerAddresses(peerId string) (addrs []string, ok bool)
|
||
// CHash returns nodes consistent table
|
||
CHash() chash.CHash
|
||
// Partition returns partition number by spaceId
|
||
Partition(spaceId string) (part int)
|
||
// NodeTypes returns list of known nodeTypes by nodeId, if node not registered in configuration will return empty list
|
||
NodeTypes(nodeId string) []NodeType
|
||
}
|
||
|
||
type nodeConf struct {
|
||
id string
|
||
accountId string
|
||
filePeers []string
|
||
consensusPeers []string
|
||
coordinatorPeers []string
|
||
namingNodePeers []string
|
||
paymentProcessingNodePeers []string
|
||
chash chash.CHash
|
||
allMembers []Node
|
||
c Configuration
|
||
addrs map[string][]string
|
||
}
|
||
|
||
func (c *nodeConf) Id() string {
|
||
return c.id
|
||
}
|
||
|
||
func (c *nodeConf) Configuration() Configuration {
|
||
return c.c
|
||
}
|
||
|
||
func (c *nodeConf) NodeIds(spaceId string) []string {
|
||
members := c.chash.GetMembers(ReplKey(spaceId))
|
||
res := make([]string, 0, len(members))
|
||
for _, m := range members {
|
||
if m.Id() != c.accountId {
|
||
res = append(res, m.Id())
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
func (c *nodeConf) IsResponsible(spaceId string) bool {
|
||
for _, m := range c.chash.GetMembers(ReplKey(spaceId)) {
|
||
if m.Id() == c.accountId {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (c *nodeConf) FilePeers() []string {
|
||
return c.filePeers
|
||
}
|
||
|
||
func (c *nodeConf) ConsensusPeers() []string {
|
||
return c.consensusPeers
|
||
}
|
||
|
||
func (c *nodeConf) CoordinatorPeers() []string {
|
||
return c.coordinatorPeers
|
||
}
|
||
|
||
func (c *nodeConf) NamingNodePeers() []string {
|
||
return c.namingNodePeers
|
||
}
|
||
|
||
func (c *nodeConf) PaymentProcessingNodePeers() []string {
|
||
return c.paymentProcessingNodePeers
|
||
}
|
||
|
||
func (c *nodeConf) PeerAddresses(peerId string) (addrs []string, ok bool) {
|
||
addrs, ok = c.addrs[peerId]
|
||
if ok && len(addrs) == 0 {
|
||
return nil, false
|
||
}
|
||
return
|
||
}
|
||
|
||
func (c *nodeConf) CHash() chash.CHash {
|
||
return c.chash
|
||
}
|
||
|
||
func (c *nodeConf) Partition(spaceId string) (part int) {
|
||
return c.chash.GetPartition(ReplKey(spaceId))
|
||
}
|
||
|
||
func (c *nodeConf) NodeTypes(nodeId string) []NodeType {
|
||
for _, m := range c.allMembers {
|
||
if m.PeerId == nodeId {
|
||
return m.Types
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func ReplKey(spaceId string) (replKey string) {
|
||
if i := strings.LastIndex(spaceId, "."); i != -1 {
|
||
return spaceId[i+1:]
|
||
}
|
||
return spaceId
|
||
}
|
||
|
||
func сonfigurationToNodeConf(c Configuration) (nc *nodeConf, err error) {
|
||
nc = &nodeConf{
|
||
id: c.Id,
|
||
c: c,
|
||
|
||
// WARN: do not forget to set it later, Configuration does not feature it
|
||
//accountId: s.accountId,
|
||
|
||
addrs: map[string][]string{},
|
||
}
|
||
if nc.chash, err = chash.New(chash.Config{
|
||
PartitionCount: PartitionCount,
|
||
ReplicationFactor: ReplicationFactor,
|
||
}); err != nil {
|
||
return
|
||
}
|
||
|
||
members := make([]chash.Member, 0, len(c.Nodes))
|
||
for _, n := range c.Nodes {
|
||
if n.HasType(NodeTypeTree) {
|
||
members = append(members, n)
|
||
}
|
||
if n.HasType(NodeTypeConsensus) {
|
||
nc.consensusPeers = append(nc.consensusPeers, n.PeerId)
|
||
}
|
||
if n.HasType(NodeTypeFile) {
|
||
nc.filePeers = append(nc.filePeers, n.PeerId)
|
||
}
|
||
if n.HasType(NodeTypeCoordinator) {
|
||
nc.coordinatorPeers = append(nc.coordinatorPeers, n.PeerId)
|
||
}
|
||
if n.HasType(NodeTypeNamingNode) {
|
||
nc.namingNodePeers = append(nc.namingNodePeers, n.PeerId)
|
||
}
|
||
if n.HasType(NodeTypePaymentProcessingNode) {
|
||
nc.paymentProcessingNodePeers = append(nc.paymentProcessingNodePeers, n.PeerId)
|
||
}
|
||
|
||
nc.allMembers = append(nc.allMembers, n)
|
||
nc.addrs[n.PeerId] = n.Addresses
|
||
}
|
||
err = nc.chash.AddMembers(members...)
|
||
return
|
||
}
|