package indexer import ( "context" "oc-discovery/conf" "oc-discovery/daemons/node/common" "sync" oclib "cloud.o-forge.io/core/oc-lib" dht "github.com/libp2p/go-libp2p-kad-dht" pubsub "github.com/libp2p/go-libp2p-pubsub" record "github.com/libp2p/go-libp2p-record" "github.com/libp2p/go-libp2p/core/host" ) // IndexerService manages the indexer node's state: stream records, DHT, pubsub. type IndexerService struct { *common.LongLivedStreamRecordedService[PeerRecord] PS *pubsub.PubSub DHT *dht.IpfsDHT isStrictIndexer bool mu sync.RWMutex IsNative bool Native *NativeState // non-nil when IsNative == true } // 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 { logger := oclib.GetLogger() logger.Info().Msg("open indexer mode...") var err error ix := &IndexerService{ LongLivedStreamRecordedService: common.NewStreamRecordedService[PeerRecord](h, maxNode), isStrictIndexer: ps == nil, IsNative: isNative, } if ps == nil { ps, err = pubsub.NewGossipSub(context.Background(), ix.Host) if err != nil { panic(err) // can't run your indexer without a propagation pubsub } } ix.PS = ps if ix.isStrictIndexer { logger.Info().Msg("connect to indexers as strict indexer...") common.ConnectToIndexers(h, 0, 5, ix.Host.ID()) logger.Info().Msg("subscribe to decentralized search flow as strict indexer...") ix.SubscribeToSearch(ix.PS, nil) } if ix.DHT, err = dht.New( context.Background(), ix.Host, dht.Mode(dht.ModeServer), dht.Validator(record.NamespacedValidator{ "node": PeerRecordValidator{}, "indexer": IndexerRecordValidator{}, // for native indexer registry }), ); err != nil { return nil } // 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) } return ix } func (ix *IndexerService) Close() { ix.DHT.Close() ix.PS.UnregisterTopicValidator(common.TopicPubSubSearch) for _, s := range ix.StreamRecords { for _, ss := range s { ss.HeartbeatStream.Stream.Close() } } }