2026-01-30 16:57:36 +01:00
|
|
|
package indexer
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"oc-discovery/daemons/node/common"
|
2026-02-04 11:35:19 +01:00
|
|
|
"sync"
|
2026-01-30 16:57:36 +01:00
|
|
|
|
2026-02-02 09:05:58 +01:00
|
|
|
oclib "cloud.o-forge.io/core/oc-lib"
|
2026-02-04 11:35:19 +01:00
|
|
|
pp "cloud.o-forge.io/core/oc-lib/models/peer"
|
2026-01-30 16:57:36 +01:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
|
|
|
"github.com/libp2p/go-libp2p/core/host"
|
2026-02-04 11:35:19 +01:00
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
2026-01-30 16:57:36 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Index Record is the model for the specialized registry of node connected to Indexer
|
|
|
|
|
type IndexerService struct {
|
|
|
|
|
*common.LongLivedStreamRecordedService[PeerRecord]
|
|
|
|
|
PS *pubsub.PubSub
|
|
|
|
|
isStrictIndexer bool
|
2026-02-04 11:35:19 +01:00
|
|
|
mu sync.RWMutex
|
|
|
|
|
DisposedPeers map[peer.ID]*common.TopicNodeActivityPub
|
2026-01-30 16:57:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if a pubsub is given... indexer is also an active oc-node. If not... your a strict indexer
|
|
|
|
|
func NewIndexerService(h host.Host, ps *pubsub.PubSub, maxNode int) *IndexerService {
|
2026-02-02 09:05:58 +01:00
|
|
|
logger := oclib.GetLogger()
|
|
|
|
|
logger.Info().Msg("open indexer mode...")
|
2026-01-30 16:57:36 +01:00
|
|
|
var err error
|
|
|
|
|
ix := &IndexerService{
|
|
|
|
|
LongLivedStreamRecordedService: common.NewStreamRecordedService[PeerRecord](h, maxNode, false),
|
|
|
|
|
isStrictIndexer: ps == nil,
|
|
|
|
|
}
|
|
|
|
|
if ps == nil { // generate your fresh gossip for the flow of killed node... EVERYBODY should know !
|
|
|
|
|
ps, err = pubsub.NewGossipSub(context.Background(), ix.Host)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err) // can't run your indexer without a propalgation pubsub, of state of node.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ix.PS = ps
|
|
|
|
|
// later TODO : all indexer laucnh a private replica of them self. DEV OPS
|
|
|
|
|
if ix.isStrictIndexer {
|
2026-02-02 09:05:58 +01:00
|
|
|
logger.Info().Msg("connect to indexers as strict indexer...")
|
2026-01-30 16:57:36 +01:00
|
|
|
common.ConnectToIndexers(h, 0, 5, ix.Host.ID()) // TODO : make var to change how many indexers are allowed.
|
2026-02-02 09:05:58 +01:00
|
|
|
logger.Info().Msg("subscribe to node activity as strict indexer...")
|
2026-02-04 11:35:19 +01:00
|
|
|
|
2026-02-02 09:05:58 +01:00
|
|
|
logger.Info().Msg("subscribe to decentralized search flow as strict indexer...")
|
2026-02-04 11:35:19 +01:00
|
|
|
ix.SubscribeToSearch(ix.PS, nil)
|
|
|
|
|
}
|
|
|
|
|
f := func(ctx context.Context, evt common.TopicNodeActivityPub, _ string) {
|
|
|
|
|
ix.mu.Lock()
|
2026-02-09 13:28:00 +01:00
|
|
|
if pid, err := peer.Decode(evt.PeerID); err == nil {
|
|
|
|
|
if evt.NodeActivity == pp.OFFLINE.EnumIndex() {
|
|
|
|
|
delete(ix.DisposedPeers, pid)
|
|
|
|
|
}
|
|
|
|
|
if evt.NodeActivity == pp.ONLINE.EnumIndex() {
|
|
|
|
|
ix.DisposedPeers[pid] = &evt
|
|
|
|
|
}
|
2026-02-04 11:35:19 +01:00
|
|
|
}
|
2026-02-09 13:28:00 +01:00
|
|
|
|
2026-02-04 11:35:19 +01:00
|
|
|
ix.mu.Unlock()
|
2026-01-30 16:57:36 +01:00
|
|
|
}
|
2026-02-04 11:35:19 +01:00
|
|
|
ix.SubscribeToNodeActivity(ix.PS, &f) // now we subscribe to a long run topic named node-activity, to relay message.
|
|
|
|
|
ix.initNodeHandler() // then listen up on every protocol expected
|
2026-01-30 16:57:36 +01:00
|
|
|
return ix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ix *IndexerService) Close() {
|
|
|
|
|
for _, s := range ix.StreamRecords {
|
|
|
|
|
for _, ss := range s {
|
|
|
|
|
ss.Stream.Close()
|
|
|
|
|
ss.HeartbeatStream.Stream.Close()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|