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 ConfigurationToNodeConf(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
|
|
}
|