Files
oc-discovery/daemons/node/indexer/service.go

88 lines
2.4 KiB
Go
Raw Normal View History

2026-01-30 16:57:36 +01:00
package indexer
import (
"context"
2026-02-20 12:42:18 +01:00
"oc-discovery/conf"
2026-01-30 16:57:36 +01:00
"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"
dht "github.com/libp2p/go-libp2p-kad-dht"
2026-01-30 16:57:36 +01:00
pubsub "github.com/libp2p/go-libp2p-pubsub"
record "github.com/libp2p/go-libp2p-record"
2026-01-30 16:57:36 +01:00
"github.com/libp2p/go-libp2p/core/host"
)
2026-02-20 12:42:18 +01:00
// IndexerService manages the indexer node's state: stream records, DHT, pubsub.
2026-01-30 16:57:36 +01:00
type IndexerService struct {
*common.LongLivedStreamRecordedService[PeerRecord]
PS *pubsub.PubSub
DHT *dht.IpfsDHT
2026-01-30 16:57:36 +01:00
isStrictIndexer bool
2026-02-04 11:35:19 +01:00
mu sync.RWMutex
2026-02-20 12:42:18 +01:00
IsNative bool
Native *NativeState // non-nil when IsNative == true
2026-01-30 16:57:36 +01:00
}
2026-02-20 12:42:18 +01:00
// NewIndexerService creates an IndexerService.
// If ps is nil, this is a strict indexer (no pre-existing gossip sub from a node).
func NewIndexerService(h host.Host, ps *pubsub.PubSub, maxNode int, isNative bool) *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{
2026-02-20 12:42:18 +01:00
LongLivedStreamRecordedService: common.NewStreamRecordedService[PeerRecord](h, maxNode),
2026-01-30 16:57:36 +01:00
isStrictIndexer: ps == nil,
2026-02-20 12:42:18 +01:00
IsNative: isNative,
2026-01-30 16:57:36 +01:00
}
2026-02-20 12:42:18 +01:00
if ps == nil {
2026-01-30 16:57:36 +01:00
ps, err = pubsub.NewGossipSub(context.Background(), ix.Host)
if err != nil {
2026-02-20 12:42:18 +01:00
panic(err) // can't run your indexer without a propagation pubsub
2026-01-30 16:57:36 +01:00
}
}
ix.PS = ps
2026-02-20 12:42:18 +01:00
2026-01-30 16:57:36 +01:00
if ix.isStrictIndexer {
2026-02-02 09:05:58 +01:00
logger.Info().Msg("connect to indexers as strict indexer...")
2026-02-20 12:42:18 +01:00
common.ConnectToIndexers(h, 0, 5, ix.Host.ID())
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)
}
2026-02-20 12:42:18 +01:00
if ix.DHT, err = dht.New(
context.Background(),
ix.Host,
dht.Mode(dht.ModeServer),
dht.Validator(record.NamespacedValidator{
2026-02-20 12:42:18 +01:00
"node": PeerRecordValidator{},
"indexer": IndexerRecordValidator{}, // for native indexer registry
}),
); err != nil {
return nil
2026-01-30 16:57:36 +01:00
}
2026-02-20 12:42:18 +01:00
// InitNative must happen after DHT is ready
if isNative {
ix.InitNative()
} else {
ix.initNodeHandler()
}
// Register with configured natives so this indexer appears in their cache
if nativeAddrs := conf.GetConfig().NativeIndexerAddresses; nativeAddrs != "" {
StartNativeRegistration(ix.Host, nativeAddrs)
}
2026-01-30 16:57:36 +01:00
return ix
}
func (ix *IndexerService) Close() {
ix.DHT.Close()
ix.PS.UnregisterTopicValidator(common.TopicPubSubSearch)
2026-01-30 16:57:36 +01:00
for _, s := range ix.StreamRecords {
for _, ss := range s {
ss.HeartbeatStream.Stream.Close()
}
}
}