Discovery Neo Oclib

This commit is contained in:
mr
2026-05-27 16:17:00 +02:00
parent 7f951afd41
commit 6ce6e6fe7d
20 changed files with 1436 additions and 1133 deletions
+33 -12
View File
@@ -29,7 +29,7 @@ var retryRunning atomic.Bool
// peer has at least 3 chances to respond or refute the suspicion signal.
const suspectTimeout = 3 * RecommendedHeartbeatInterval
func ConnectToIndexers(h host.Host, minIndexer int, maxIndexer int, recordFn ...func() json.RawMessage) error {
func ConnectToIndexers(h host.Host, minIndexer int, maxIndexer int, hooks ...HeartbeatHooks) error {
TimeWatcher = time.Now().UTC()
logger := oclib.GetLogger()
@@ -71,7 +71,7 @@ func ConnectToIndexers(h host.Host, minIndexer int, maxIndexer int, recordFn ...
// Start long-lived heartbeat to seed indexers. The single goroutine follows
// all subsequent StaticIndexers changes.
SendHeartbeat(context.Background(), ProtocolHeartbeat, conf.GetConfig().Name,
h, Indexers, 20*time.Second, maxIndexer, recordFn...)
h, Indexers, 20*time.Second, maxIndexer, hooks...)
// Watch for inbound connections: if a peer connects to us and our pool has
// room, probe it first to confirm it supports ProtocolHeartbeat (i.e. it is
@@ -270,17 +270,29 @@ func handleSuggestions(d *Directory, from string, suggestions []pp.AddrInfo) {
}
}
// HeartbeatHooks carries optional callbacks injected into the heartbeat loop.
type HeartbeatHooks struct {
// RecordFn returns a fresh signed PeerRecord for embedding in each heartbeat.
RecordFn func() json.RawMessage
// PendingContactFn returns the list of peer IDs for which the caller has
// undelivered critical DTN entries. Called on every tick.
PendingContactFn func() []string
// OnPendingCallers is invoked when an indexer response contains peer IDs
// that have undelivered messages for us. The caller should initiate contact
// with each of them so they can flush their DTN cache.
OnPendingCallers func(callerPeerIDs []string)
}
// SendHeartbeat starts a goroutine that sends periodic heartbeats to peers.
// recordFn, when provided, is called on each tick and its output is embedded in
// the heartbeat as a fresh signed PeerRecord so the receiving indexer can
// republish it to the DHT without an extra round-trip.
// Pass no recordFn (or nil) for indexer→indexer / native heartbeats.
func SendHeartbeat(ctx context.Context, proto protocol.ID, name string, h host.Host, directory *Directory, interval time.Duration, maxPool int, recordFn ...func() json.RawMessage) {
// hooks.RecordFn, when set, is called on each tick and its output is embedded
// in the heartbeat as a fresh signed PeerRecord.
// Pass an empty HeartbeatHooks (or none) for indexer→indexer / native heartbeats.
func SendHeartbeat(ctx context.Context, proto protocol.ID, name string, h host.Host, directory *Directory, interval time.Duration, maxPool int, hooks ...HeartbeatHooks) {
logger := oclib.GetLogger()
isIndexerHB := directory == Indexers
var recFn func() json.RawMessage
if len(recordFn) > 0 {
recFn = recordFn[0]
var hk HeartbeatHooks
if len(hooks) > 0 {
hk = hooks[0]
}
go func() {
logger.Info().Str("proto", string(proto)).Int("peers", len(directory.Addrs)).Msg("heartbeat started")
@@ -306,8 +318,11 @@ func SendHeartbeat(ctx context.Context, proto protocol.ID, name string, h host.H
IndexersBinded: addrs,
Need: need,
}
if recFn != nil {
baseHB.Record = recFn()
if hk.RecordFn != nil {
baseHB.Record = hk.RecordFn()
}
if hk.PendingContactFn != nil {
baseHB.PendingContact = hk.PendingContactFn()
}
// Piggyback SWIM membership events on every outgoing heartbeat batch.
// All peers in the pool receive the same events this tick.
@@ -550,6 +565,12 @@ func SendHeartbeat(ctx context.Context, proto protocol.ID, name string, h host.H
handleSuggestions(directory, ai.Info.ID.String(), resp.Suggestions)
}
// PendingCallers: peers that have undelivered DTN messages for us.
// Signal the DTN layer so it can flush immediately when it reaches them.
if resp != nil && len(resp.PendingCallers) > 0 && hk.OnPendingCallers != nil {
hk.OnPendingCallers(resp.PendingCallers)
}
// Handle SuggestMigrate: indexer is overloaded and wants us to move.
if resp != nil && resp.SuggestMigrate && isIndexerHB {
nonSeedCount := 0