refactor: use a dependency injection/IoC pattern based off uber fx

This commit is contained in:
Derrick Hammer 2024-01-29 01:10:04 -05:00
parent 384557de0c
commit 59a73e4266
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
10 changed files with 175 additions and 102 deletions

2
go.mod
View File

@ -15,6 +15,7 @@ require (
github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/vmihailenco/msgpack/v5 v5.4.1
go.etcd.io/bbolt v1.3.8 go.etcd.io/bbolt v1.3.8
go.sia.tech/jape v0.11.1 go.sia.tech/jape v0.11.1
go.uber.org/fx v1.20.1
go.uber.org/zap v1.26.0 go.uber.org/zap v1.26.0
nhooyr.io/websocket v1.7.1 nhooyr.io/websocket v1.7.1
) )
@ -26,6 +27,7 @@ require (
github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.uber.org/dig v1.17.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.17.0 // indirect

View File

@ -17,7 +17,6 @@ import (
"github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
"go.uber.org/zap" "go.uber.org/zap"
"sync"
"time" "time"
) )
@ -26,11 +25,9 @@ const cacheBucketName = "object-cache"
type Node struct { type Node struct {
nodeConfig *config.NodeConfig nodeConfig *config.NodeConfig
metadataCache structs.Map metadataCache structs.Map
started bool
hashQueryRoutingTable structs.Map hashQueryRoutingTable structs.Map
services service.Services services service.Services
httpClient *resty.Client httpClient *resty.Client
connections sync.WaitGroup
providerStore storage.ProviderStore providerStore storage.ProviderStore
} }
@ -42,24 +39,21 @@ func (n *Node) Services() service.Services {
return n.services return n.services
} }
func NewNode(config *config.NodeConfig) *Node { func NewNode(config *config.NodeConfig, services service.Services) *Node {
n := &Node{ return &Node{
nodeConfig: config, nodeConfig: config,
metadataCache: structs.NewMap(), metadataCache: structs.NewMap(),
started: false,
hashQueryRoutingTable: structs.NewMap(), hashQueryRoutingTable: structs.NewMap(),
httpClient: resty.New(), httpClient: resty.New(),
services: services, // Services are passed in, not created here
} }
n.services = NewServices(service.NewP2P(n), service.NewRegistry(n), service.NewHTTP(n))
return n
} }
func (n *Node) HashQueryRoutingTable() structs.Map { func (n *Node) HashQueryRoutingTable() structs.Map {
return n.hashQueryRoutingTable return n.hashQueryRoutingTable
} }
func (n *Node) IsStarted() bool { func (n *Node) IsStarted() bool {
return n.started return n.services.IsStarted()
} }
func (n *Node) Config() *config.NodeConfig { func (n *Node) Config() *config.NodeConfig {
@ -81,8 +75,8 @@ func (n *Node) Db() *bolt.DB {
} }
func (n *Node) Start() error { func (n *Node) Start() error {
protocol.Init() protocol.RegisterProtocols()
signed.Init() signed.RegisterSignedProtocols()
err := err :=
utils.CreateBucket(cacheBucketName, n.Db()) utils.CreateBucket(cacheBucketName, n.Db())
@ -90,22 +84,13 @@ func (n *Node) Start() error {
return err return err
} }
n.started = true return n.services.Start()
for _, svc := range n.services.All() {
err := svc.Init()
if err != nil {
return err
} }
err = svc.Start() func (n *Node) Stop() error {
if err != nil { return n.services.Stop()
return err
}
}
n.started = true
return nil
} }
func (n *Node) GetCachedStorageLocations(hash *encoding.Multihash, kinds []types.StorageLocationType) (map[string]storage.StorageLocation, error) { func (n *Node) GetCachedStorageLocations(hash *encoding.Multihash, kinds []types.StorageLocationType) (map[string]storage.StorageLocation, error) {
locations := make(map[string]storage.StorageLocation) locations := make(map[string]storage.StorageLocation)
@ -325,11 +310,7 @@ func (n *Node) GetMetadataByCID(cid *encoding.CID) (md metadata.Metadata, err er
return md, nil return md, nil
} }
func (n *Node) WaitOnConnectedPeers() { func (n *Node) WaitOnConnectedPeers() {
n.connections.Wait() n.services.P2P().WaitOnConnectedPeers()
}
func (n *Node) ConnectionTracker() *sync.WaitGroup {
return &n.connections
} }
func (n *Node) SetProviderStore(store storage.ProviderStore) { func (n *Node) SetProviderStore(store storage.ProviderStore) {
@ -339,3 +320,26 @@ func (n *Node) SetProviderStore(store storage.ProviderStore) {
func (n *Node) ProviderStore() storage.ProviderStore { func (n *Node) ProviderStore() storage.ProviderStore {
return n.providerStore return n.providerStore
} }
func DefaultNode(config *config.NodeConfig) *Node {
params := service.ServiceParams{
Logger: config.Logger,
Config: config,
Db: config.DB,
}
// Initialize services first
p2pService := service.NewP2P(params)
registryService := service.NewRegistry(params)
httpService := service.NewHTTP(params)
// Aggregate services
services := NewServices(ServicesParams{
P2P: p2pService,
Registry: registryService,
HTTP: httpService,
})
// Now create the node with the services
return NewNode(config, services)
}

View File

@ -8,10 +8,17 @@ var (
_ service.Services = (*ServicesImpl)(nil) _ service.Services = (*ServicesImpl)(nil)
) )
type ServicesParams struct {
P2P *service.P2PService
Registry *service.RegistryService
HTTP *service.HTTPService
}
type ServicesImpl struct { type ServicesImpl struct {
p2p *service.P2PService p2p *service.P2PService
registry *service.RegistryService registry *service.RegistryService
http *service.HTTPService http *service.HTTPService
started bool
} }
func (s *ServicesImpl) HTTP() *service.HTTPService { func (s *ServicesImpl) HTTP() *service.HTTPService {
@ -31,14 +38,50 @@ func (s *ServicesImpl) Registry() *service.RegistryService {
return s.registry return s.registry
} }
func NewServices(p2p *service.P2PService, registry *service.RegistryService, http *service.HTTPService) service.Services { func NewServices(params ServicesParams) service.Services {
return &ServicesImpl{ sc := &ServicesImpl{
p2p: p2p, p2p: params.P2P,
registry: registry, registry: params.Registry,
http: http, http: params.HTTP,
started: false,
} }
for _, svc := range sc.All() {
svc.SetServices(sc)
}
return sc
} }
func (s *ServicesImpl) P2P() *service.P2PService { func (s *ServicesImpl) P2P() *service.P2PService {
return s.p2p return s.p2p
} }
func (s *ServicesImpl) IsStarted() bool {
return s.started
}
func (s *ServicesImpl) Start() error {
for _, svc := range s.All() {
err := svc.Start()
if err != nil {
return err
}
}
s.started = true
return nil
}
func (s *ServicesImpl) Stop() error {
for _, svc := range s.All() {
err := svc.Stop()
if err != nil {
return err
}
}
s.started = false
return nil
}

View File

@ -10,7 +10,7 @@ var (
messageTypes map[int]func() base.IncomingMessage messageTypes map[int]func() base.IncomingMessage
) )
func Init() { func RegisterProtocols() {
messageTypes = make(map[int]func() base.IncomingMessage) messageTypes = make(map[int]func() base.IncomingMessage)
// Register factory functions instead of instances // Register factory functions instead of instances

View File

@ -22,7 +22,7 @@ var (
messageTypes map[int]func() IncomingMessageSigned messageTypes map[int]func() IncomingMessageSigned
) )
func Init() { func RegisterSignedProtocols() {
messageTypes = make(map[int]func() IncomingMessageSigned) messageTypes = make(map[int]func() IncomingMessageSigned)
RegisterMessageType(int(types.ProtocolMethodHandshakeDone), func() IncomingMessageSigned { RegisterMessageType(int(types.ProtocolMethodHandshakeDone), func() IncomingMessageSigned {

View File

@ -3,8 +3,8 @@ package signed
import ( import (
"crypto/ed25519" "crypto/ed25519"
"errors" "errors"
"git.lumeweb.com/LumeWeb/libs5-go/config"
"git.lumeweb.com/LumeWeb/libs5-go/encoding" "git.lumeweb.com/LumeWeb/libs5-go/encoding"
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base" "git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
"git.lumeweb.com/LumeWeb/libs5-go/types" "git.lumeweb.com/LumeWeb/libs5-go/types"
"github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5"
@ -171,7 +171,7 @@ func (s *SignedMessage) EncodeMsgpack(enc *msgpack.Encoder) error {
return nil return nil
} }
func (s *SignedMessage) Sign(node *_node.Node) error { func (s *SignedMessage) Sign(cfg *config.NodeConfig) error {
if s.nodeId == nil { if s.nodeId == nil {
panic("nodeId is nil") panic("nodeId is nil")
} }
@ -180,7 +180,7 @@ func (s *SignedMessage) Sign(node *_node.Node) error {
panic("message is nil") panic("message is nil")
} }
s.signature = ed25519.Sign(node.Config().KeyPair.ExtractBytes(), s.message) s.signature = ed25519.Sign(cfg.KeyPair.ExtractBytes(), s.message)
return nil return nil
} }

View File

@ -3,7 +3,6 @@ package service
import ( import (
"git.lumeweb.com/LumeWeb/libs5-go/build" "git.lumeweb.com/LumeWeb/libs5-go/build"
"git.lumeweb.com/LumeWeb/libs5-go/net" "git.lumeweb.com/LumeWeb/libs5-go/net"
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"go.sia.tech/jape" "go.sia.tech/jape"
"go.uber.org/zap" "go.uber.org/zap"
@ -23,12 +22,16 @@ type P2PNodeResponse struct {
} }
type HTTPService struct { type HTTPService struct {
node *_node.Node ServiceBase
} }
func NewHTTP(node *_node.Node) *HTTPService { func NewHTTP(params ServiceParams) *HTTPService {
return &HTTPService{ return &HTTPService{
node: node, ServiceBase: ServiceBase{
logger: params.Logger,
config: params.Config,
db: params.Db,
},
} }
} }
@ -46,10 +49,6 @@ func (h *HTTPService) GetHttpRouter(inject map[string]jape.Handler) *httprouter.
return jape.Mux(routes) return jape.Mux(routes)
} }
func (h *HTTPService) Node() *_node.Node {
return h.node
}
func (h *HTTPService) Start() error { func (h *HTTPService) Start() error {
return nil return nil
} }
@ -68,7 +67,7 @@ func (h *HTTPService) versionHandler(ctx jape.Context) {
func (h *HTTPService) p2pHandler(ctx jape.Context) { func (h *HTTPService) p2pHandler(ctx jape.Context) {
c, err := websocket.Accept(ctx.ResponseWriter, ctx.Request, nil) c, err := websocket.Accept(ctx.ResponseWriter, ctx.Request, nil)
if err != nil { if err != nil {
h.node.Logger().Error("error accepting websocket connection", zap.Error(err)) h.logger.Error("error accepting websocket connection", zap.Error(err))
return return
} }
@ -78,33 +77,33 @@ func (h *HTTPService) p2pHandler(ctx jape.Context) {
}) })
if err != nil { if err != nil {
h.node.Logger().Error("error creating transport peer", zap.Error(err)) h.logger.Error("error creating transport peer", zap.Error(err))
err := c.Close(websocket.StatusInternalError, "the sky is falling") err := c.Close(websocket.StatusInternalError, "the sky is falling")
if err != nil { if err != nil {
h.node.Logger().Error("error closing websocket connection", zap.Error(err)) h.logger.Error("error closing websocket connection", zap.Error(err))
} }
return return
} }
h.Node().ConnectionTracker().Add(1) h.services.P2P().ConnectionTracker().Add(1)
go func() { go func() {
err := h.node.Services().P2P().OnNewPeer(peer, false) err := h.services.P2P().OnNewPeer(peer, false)
if err != nil { if err != nil {
h.node.Logger().Error("error handling new peer", zap.Error(err)) h.logger.Error("error handling new peer", zap.Error(err))
} }
h.node.ConnectionTracker().Done() h.services.P2P().ConnectionTracker().Done()
}() }()
} }
func (h *HTTPService) p2pNodesHandler(ctx jape.Context) { func (h *HTTPService) p2pNodesHandler(ctx jape.Context) {
localId, err := h.node.Services().P2P().NodeId().ToString() localId, err := h.services.P2P().NodeId().ToString()
if ctx.Check("error getting local node id", err) != nil { if ctx.Check("error getting local node id", err) != nil {
return return
} }
uris := h.node.Services().P2P().SelfConnectionUris() uris := h.services.P2P().SelfConnectionUris()
nodeList := make([]P2PNodeResponse, len(uris)) nodeList := make([]P2PNodeResponse, len(uris))

View File

@ -9,7 +9,6 @@ import (
"git.lumeweb.com/LumeWeb/libs5-go/ed25519" "git.lumeweb.com/LumeWeb/libs5-go/ed25519"
"git.lumeweb.com/LumeWeb/libs5-go/encoding" "git.lumeweb.com/LumeWeb/libs5-go/encoding"
"git.lumeweb.com/LumeWeb/libs5-go/net" "git.lumeweb.com/LumeWeb/libs5-go/net"
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
"git.lumeweb.com/LumeWeb/libs5-go/protocol" "git.lumeweb.com/LumeWeb/libs5-go/protocol"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base" "git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/signed" "git.lumeweb.com/LumeWeb/libs5-go/protocol/signed"
@ -36,12 +35,10 @@ var (
const nodeBucketName = "nodes" const nodeBucketName = "nodes"
type P2PService struct { type P2PService struct {
logger *zap.Logger
nodeKeyPair *ed25519.KeyPairEd25519 nodeKeyPair *ed25519.KeyPairEd25519
localNodeID *encoding.NodeId localNodeID *encoding.NodeId
networkID string networkID string
nodesBucket *bolt.Bucket nodesBucket *bolt.Bucket
node *_node.Node
inited bool inited bool
reconnectDelay structs.Map reconnectDelay structs.Map
peers structs.Map peers structs.Map
@ -52,19 +49,19 @@ type P2PService struct {
incomingIPBlocklist structs.Map incomingIPBlocklist structs.Map
outgoingPeerFailures structs.Map outgoingPeerFailures structs.Map
maxOutgoingPeerFailures uint maxOutgoingPeerFailures uint
connections sync.WaitGroup
ServiceBase
} }
func NewP2P(node *_node.Node) *P2PService { func NewP2P(params ServiceParams) *P2PService {
uri, err := url.Parse(fmt.Sprintf("wss://%s:%d/s5/p2p", node.Config().HTTP.API.Domain, node.Config().HTTP.API.Port)) uri, err := url.Parse(fmt.Sprintf("wss://%s:%d/s5/p2p", params.Config.HTTP.API.Domain, params.Config.HTTP.API.Port))
if err != nil { if err != nil {
node.Logger().Fatal("failed to HTTP API URL Config", zap.Error(err)) params.Logger.Fatal("failed to parse HTTP API URL", zap.Error(err))
} }
service := &P2PService{ service := &P2PService{
logger: node.Logger(), nodeKeyPair: params.Config.KeyPair,
nodeKeyPair: node.Config().KeyPair, networkID: params.Config.P2P.Network,
networkID: node.Config().P2P.Network,
node: node,
inited: false, inited: false,
reconnectDelay: structs.NewMap(), reconnectDelay: structs.NewMap(),
peers: structs.NewMap(), peers: structs.NewMap(),
@ -74,7 +71,12 @@ func NewP2P(node *_node.Node) *P2PService {
incomingPeerBlockList: structs.NewMap(), incomingPeerBlockList: structs.NewMap(),
incomingIPBlocklist: structs.NewMap(), incomingIPBlocklist: structs.NewMap(),
outgoingPeerFailures: structs.NewMap(), outgoingPeerFailures: structs.NewMap(),
maxOutgoingPeerFailures: node.Config().P2P.MaxOutgoingPeerFailures, maxOutgoingPeerFailures: params.Config.P2P.MaxOutgoingPeerFailures,
ServiceBase: ServiceBase{
logger: params.Logger,
config: params.Config,
db: params.Db,
},
} }
return service return service
@ -84,16 +86,12 @@ func (p *P2PService) SelfConnectionUris() []*url.URL {
return p.selfConnectionUris return p.selfConnectionUris
} }
func (p *P2PService) Node() *_node.Node {
return p.node
}
func (p *P2PService) Peers() structs.Map { func (p *P2PService) Peers() structs.Map {
return p.peers return p.peers
} }
func (p *P2PService) Start() error { func (p *P2PService) Start() error {
config := p.Node().Config() config := p.config
if len(config.P2P.Peers.Initial) > 0 { if len(config.P2P.Peers.Initial) > 0 {
initialPeers := config.P2P.Peers.Initial initialPeers := config.P2P.Peers.Initial
@ -117,7 +115,7 @@ func (p *P2PService) Start() error {
} }
func (p *P2PService) Stop() error { func (p *P2PService) Stop() error {
panic("implement me") return nil
} }
func (p *P2PService) Init() error { func (p *P2PService) Init() error {
@ -126,7 +124,7 @@ func (p *P2PService) Init() error {
} }
p.localNodeID = encoding.NewNodeId(p.nodeKeyPair.PublicKey()) p.localNodeID = encoding.NewNodeId(p.nodeKeyPair.PublicKey())
err := utils.CreateBucket(nodeBucketName, p.Node().Db()) err := utils.CreateBucket(nodeBucketName, p.db)
if err != nil { if err != nil {
return err return err
@ -137,7 +135,7 @@ func (p *P2PService) Init() error {
return nil return nil
} }
func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, fromPeer net.Peer) error { func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, fromPeer net.Peer) error {
if !p.Node().IsStarted() { if !p.services.IsStarted() {
return nil return nil
} }
@ -322,7 +320,7 @@ func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, from
peer.SetId(id) peer.SetId(id)
p.Node().ConnectionTracker().Add(1) p.services.P2P().ConnectionTracker().Add(1)
peerId, err := peer.Id().ToString() peerId, err := peer.Id().ToString()
if err != nil { if err != nil {
@ -335,7 +333,7 @@ func (p *P2PService) ConnectToNode(connectionUris []*url.URL, retried bool, from
if err != nil && !peer.Abuser() { if err != nil && !peer.Abuser() {
p.logger.Error("peer error", zap.Error(err)) p.logger.Error("peer error", zap.Error(err))
} }
p.Node().ConnectionTracker().Done() p.services.P2P().ConnectionTracker().Done()
}() }()
return nil return nil
@ -443,7 +441,6 @@ func (p *P2PService) OnNewPeerListen(peer net.Peer, verifyId bool) {
Original: message, Original: message,
Data: reader.Data, Data: reader.Data,
Ctx: context.Background(), Ctx: context.Background(),
Node: p.node,
Peer: peer, Peer: peer,
VerifyId: verifyId, VerifyId: verifyId,
} }
@ -473,7 +470,7 @@ func (p *P2PService) OnNewPeerListen(peer net.Peer, verifyId bool) {
func (p *P2PService) readNodeVotes(nodeId *encoding.NodeId) (NodeVotes, error) { func (p *P2PService) readNodeVotes(nodeId *encoding.NodeId) (NodeVotes, error) {
var value []byte var value []byte
var found bool var found bool
err := p.node.Db().View(func(tx *bolt.Tx) error { err := p.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(nodeBucketName)) b := tx.Bucket([]byte(nodeBucketName))
if b == nil { if b == nil {
return fmt.Errorf("Bucket %s not found", nodeBucketName) return fmt.Errorf("Bucket %s not found", nodeBucketName)
@ -509,7 +506,7 @@ func (p *P2PService) saveNodeVotes(nodeId *encoding.NodeId, votes NodeVotes) err
} }
// Use a transaction to save the data // Use a transaction to save the data
err = p.node.Db().Update(func(tx *bolt.Tx) error { err = p.db.Update(func(tx *bolt.Tx) error {
// Get or create the bucket // Get or create the bucket
b := tx.Bucket([]byte(nodeBucketName)) b := tx.Bucket([]byte(nodeBucketName))
@ -557,7 +554,7 @@ func (p *P2PService) SignMessageSimple(message []byte) ([]byte, error) {
signedMessage := signed.NewSignedMessageRequest(message) signedMessage := signed.NewSignedMessageRequest(message)
signedMessage.SetNodeId(p.localNodeID) signedMessage.SetNodeId(p.localNodeID)
err := signedMessage.Sign(p.Node()) err := signedMessage.Sign(p.config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -615,7 +612,7 @@ func (p *P2PService) SendHashRequest(hash *encoding.Multihash, kinds []types.Sto
for _, peer := range p.peers.Values() { for _, peer := range p.peers.Values() {
peerValue, ok := peer.(net.Peer) peerValue, ok := peer.(net.Peer)
if !ok { if !ok {
p.node.Logger().Error("failed to cast peer to net.Peer") p.logger.Error("failed to cast peer to net.Peer")
continue continue
} }
err = peerValue.SendMessage(message) err = peerValue.SendMessage(message)
@ -706,3 +703,11 @@ func (p *P2PService) PrepareProvideMessage(hash *encoding.Multihash, location st
// Return the final byte slice. // Return the final byte slice.
return finalList return finalList
} }
func (p *P2PService) WaitOnConnectedPeers() {
p.connections.Wait()
}
func (p *P2PService) ConnectionTracker() *sync.WaitGroup {
return &p.connections
}

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"git.lumeweb.com/LumeWeb/libs5-go/encoding" "git.lumeweb.com/LumeWeb/libs5-go/encoding"
"git.lumeweb.com/LumeWeb/libs5-go/net" "git.lumeweb.com/LumeWeb/libs5-go/net"
_node "git.lumeweb.com/LumeWeb/libs5-go/node"
"git.lumeweb.com/LumeWeb/libs5-go/protocol" "git.lumeweb.com/LumeWeb/libs5-go/protocol"
"git.lumeweb.com/LumeWeb/libs5-go/structs" "git.lumeweb.com/LumeWeb/libs5-go/structs"
"git.lumeweb.com/LumeWeb/libs5-go/types" "git.lumeweb.com/LumeWeb/libs5-go/types"
@ -23,14 +22,9 @@ var (
) )
type RegistryService struct { type RegistryService struct {
node *_node.Node
logger *zap.Logger
streams structs.Map streams structs.Map
subs structs.Map subs structs.Map
} ServiceBase
func (r *RegistryService) Node() *_node.Node {
return r.node
} }
func (r *RegistryService) Start() error { func (r *RegistryService) Start() error {
@ -42,15 +36,18 @@ func (r *RegistryService) Stop() error {
} }
func (r *RegistryService) Init() error { func (r *RegistryService) Init() error {
return utils.CreateBucket(registryBucketName, r.node.Db()) return utils.CreateBucket(registryBucketName, r.db)
} }
func NewRegistry(node *_node.Node) *RegistryService { func NewRegistry(params ServiceParams) *RegistryService {
return &RegistryService{ return &RegistryService{
node: node,
logger: node.Logger(),
streams: structs.NewMap(), streams: structs.NewMap(),
subs: structs.NewMap(), subs: structs.NewMap(),
ServiceBase: ServiceBase{
logger: params.Logger,
config: params.Config,
db: params.Db,
},
} }
} }
func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, receivedFrom net.Peer) error { func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, receivedFrom net.Peer) error {
@ -120,7 +117,7 @@ func (r *RegistryService) Set(sre protocol.SignedRegistryEntry, trusted bool, re
go event.Emit("fire", sre) go event.Emit("fire", sre)
} }
err = r.node.Db().Update(func(txn *bbolt.Tx) error { err = r.db.Update(func(txn *bbolt.Tx) error {
bucket := txn.Bucket([]byte(registryBucketName)) bucket := txn.Bucket([]byte(registryBucketName))
err := bucket.Put(sre.PK(), protocol.MarshalSignedRegistryEntry(sre)) err := bucket.Put(sre.PK(), protocol.MarshalSignedRegistryEntry(sre))
if err != nil { if err != nil {
@ -153,7 +150,7 @@ func (r *RegistryService) BroadcastEntry(sre protocol.SignedRegistryEntry, recei
r.logger.Debug("[registry] broadcastEntry", zap.String("pk", hashString), zap.Uint64("revision", sre.Revision()), zap.String("receivedFrom", pid)) r.logger.Debug("[registry] broadcastEntry", zap.String("pk", hashString), zap.Uint64("revision", sre.Revision()), zap.String("receivedFrom", pid))
updateMessage := protocol.MarshalSignedRegistryEntry(sre) updateMessage := protocol.MarshalSignedRegistryEntry(sre)
for _, p := range r.node.Services().P2P().Peers().Values() { for _, p := range r.services.P2P().Peers().Values() {
peer, ok := p.(net.Peer) peer, ok := p.(net.Peer)
if !ok { if !ok {
continue continue
@ -182,7 +179,7 @@ func (r *RegistryService) SendRegistryRequest(pk []byte) error {
} }
// Iterate over peers and send the request // Iterate over peers and send the request
for _, peerVal := range r.node.Services().P2P().Peers().Values() { for _, peerVal := range r.services.P2P().Peers().Values() {
peer, ok := peerVal.(net.Peer) peer, ok := peerVal.(net.Peer)
if !ok { if !ok {
continue continue
@ -295,7 +292,7 @@ func (r *RegistryService) Listen(pk []byte, cb func(sre protocol.SignedRegistryE
} }
func (r *RegistryService) getFromDB(pk []byte) (sre protocol.SignedRegistryEntry, err error) { func (r *RegistryService) getFromDB(pk []byte) (sre protocol.SignedRegistryEntry, err error) {
err = r.node.Db().View(func(txn *bbolt.Tx) error { err = r.db.View(func(txn *bbolt.Tx) error {
bucket := txn.Bucket([]byte(registryBucketName)) bucket := txn.Bucket([]byte(registryBucketName))
val := bucket.Get(pk) val := bucket.Get(pk)
if val != nil { if val != nil {

View File

@ -1,16 +1,39 @@
package service package service
import "git.lumeweb.com/LumeWeb/libs5-go/node" import (
"git.lumeweb.com/LumeWeb/libs5-go/config"
bolt "go.etcd.io/bbolt"
"go.uber.org/zap"
)
type Service interface { type Service interface {
Node() *node.Node
Start() error Start() error
Stop() error Stop() error
Init() error Init() error
SetServices(services Services)
} }
type Services interface { type Services interface {
P2P() *P2PService P2P() *P2PService
Registry() *RegistryService Registry() *RegistryService
HTTP() *HTTPService HTTP() *HTTPService
All() []Service All() []Service
IsStarted() bool
Start() error
Stop() error
}
type ServiceParams struct {
Logger *zap.Logger
Config *config.NodeConfig
Db *bolt.DB
}
type ServiceBase struct {
logger *zap.Logger
config *config.NodeConfig
db *bolt.DB
services Services
}
func (s *ServiceBase) SetServices(services Services) {
s.services = services
} }