Discovery Nano the light version.
This commit is contained in:
@@ -3,6 +3,7 @@ package indexer
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -10,8 +11,8 @@ import (
|
||||
"oc-discovery/daemons/node/common"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
pp "github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
pp "github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
const TopicSearchPeer = "oc-search-peer"
|
||||
@@ -46,31 +47,34 @@ func (ix *IndexerService) updateReferent(pid pp.ID, rec PeerRecord, referent boo
|
||||
|
||||
// searchReferenced looks up nodes in referencedNodes matching the query.
|
||||
// Matches on peerID (exact), DID (exact), or name (case-insensitive contains).
|
||||
func (ix *IndexerService) searchReferenced(peerID, did, name string) []common.SearchHit {
|
||||
func (ix *IndexerService) searchReferenced(peerID, did, name string) []PeerRecord {
|
||||
ix.referencedNodesMu.RLock()
|
||||
defer ix.referencedNodesMu.RUnlock()
|
||||
nameLow := strings.ToLower(name)
|
||||
var hits []common.SearchHit
|
||||
var hits []PeerRecord
|
||||
for pid, rec := range ix.referencedNodes {
|
||||
pidStr := pid.String()
|
||||
matchPeerID := peerID != "" && pidStr == peerID
|
||||
matchDID := did != "" && rec.DID == did
|
||||
matchName := name != "" && strings.Contains(strings.ToLower(rec.Name), nameLow)
|
||||
if matchPeerID || matchDID || matchName {
|
||||
hits = append(hits, common.SearchHit{
|
||||
PeerID: pidStr,
|
||||
DID: rec.DID,
|
||||
Name: rec.Name,
|
||||
})
|
||||
rec.ID = rec.DID
|
||||
hits = append(hits, rec)
|
||||
}
|
||||
}
|
||||
return hits
|
||||
}
|
||||
|
||||
type SearchPeerResult struct {
|
||||
QueryID string `json:"query_id"`
|
||||
Records []PeerRecord `json:"records"`
|
||||
}
|
||||
|
||||
// handleSearchPeer is the ProtocolSearchPeer handler.
|
||||
// The node opens this stream, sends a SearchPeerRequest, and reads results
|
||||
// as they stream in. The stream stays open until timeout or node closes it.
|
||||
func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
fmt.Println("handleSearchPeer")
|
||||
logger := oclib.GetLogger()
|
||||
defer s.Reset()
|
||||
|
||||
@@ -78,7 +82,7 @@ func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
logger.Warn().Str("peer", s.Conn().RemotePeer().String()).Msg("[search] unknown peer, rejecting stream")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("SearchPeerRequest")
|
||||
var req common.SearchPeerRequest
|
||||
if err := json.NewDecoder(s).Decode(&req); err != nil || req.QueryID == "" {
|
||||
return
|
||||
@@ -94,7 +98,7 @@ func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
}()
|
||||
defer streamCancel()
|
||||
|
||||
resultCh := make(chan []common.SearchHit, 16)
|
||||
resultCh := make(chan []PeerRecord, 16)
|
||||
ix.pendingSearchesMu.Lock()
|
||||
ix.pendingSearches[req.QueryID] = resultCh
|
||||
ix.pendingSearchesMu.Unlock()
|
||||
@@ -106,9 +110,10 @@ func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
|
||||
// Check own referencedNodes immediately.
|
||||
if hits := ix.searchReferenced(req.PeerID, req.DID, req.Name); len(hits) > 0 {
|
||||
fmt.Println("hits", hits)
|
||||
resultCh <- hits
|
||||
}
|
||||
|
||||
fmt.Println("publishSearchQuery")
|
||||
// Broadcast search on GossipSub so other indexers can respond.
|
||||
ix.publishSearchQuery(req.QueryID, req.PeerID, req.DID, req.Name)
|
||||
|
||||
@@ -119,7 +124,8 @@ func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
for {
|
||||
select {
|
||||
case hits := <-resultCh:
|
||||
if err := enc.Encode(common.SearchPeerResult{QueryID: req.QueryID, Records: hits}); err != nil {
|
||||
fmt.Println("resultCh hits", hits)
|
||||
if err := enc.Encode(SearchPeerResult{QueryID: req.QueryID, Records: hits}); err != nil {
|
||||
logger.Debug().Err(err).Msg("[search] stream write failed")
|
||||
return
|
||||
}
|
||||
@@ -145,13 +151,15 @@ func (ix *IndexerService) handleSearchPeer(s network.Stream) {
|
||||
// Another indexer opens this stream to deliver hits for a pending queryID.
|
||||
func (ix *IndexerService) handleSearchPeerResponse(s network.Stream) {
|
||||
defer s.Reset()
|
||||
var result common.SearchPeerResult
|
||||
fmt.Println("RECEIVED SEARCH")
|
||||
var result SearchPeerResult
|
||||
if err := json.NewDecoder(s).Decode(&result); err != nil || result.QueryID == "" {
|
||||
return
|
||||
}
|
||||
ix.pendingSearchesMu.Lock()
|
||||
ch := ix.pendingSearches[result.QueryID]
|
||||
ix.pendingSearchesMu.Unlock()
|
||||
fmt.Println("RECEIVED", result.QueryID, ix.pendingSearches[result.QueryID])
|
||||
if ch != nil {
|
||||
select {
|
||||
case ch <- result.Records:
|
||||
@@ -213,21 +221,28 @@ func (ix *IndexerService) onSearchQuery(q common.SearchQuery) {
|
||||
if q.EmitterID == ix.Host.ID().String() {
|
||||
return
|
||||
}
|
||||
fmt.Println("ON SEARCH QUERY")
|
||||
hits := ix.searchReferenced(q.PeerID, q.DID, q.Name)
|
||||
fmt.Println("ON SEARCH QUERY HITS", hits)
|
||||
if len(hits) == 0 {
|
||||
return
|
||||
}
|
||||
emitterID, err := pp.Decode(q.EmitterID)
|
||||
if err != nil {
|
||||
fmt.Println("ON SEARCH QUERY err DECODE", err)
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
s, err := ix.Host.NewStream(ctx, emitterID, common.ProtocolSearchPeerResponse)
|
||||
if err != nil {
|
||||
fmt.Println("ON SEARCH QUERY err NewStream", emitterID, err)
|
||||
return
|
||||
}
|
||||
defer s.Reset()
|
||||
fmt.Println("ON ", emitterID)
|
||||
defer s.Close()
|
||||
s.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
json.NewEncoder(s).Encode(common.SearchPeerResult{QueryID: q.QueryID, Records: hits})
|
||||
err = json.NewEncoder(s).Encode(SearchPeerResult{QueryID: q.QueryID, Records: hits})
|
||||
fmt.Println("SEARCH ERR", err)
|
||||
s.CloseWrite()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user