mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 20:06:59 +00:00
82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
package discovery
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/libp2p/go-libp2p/core/host"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// MetadataProvider is implemented by subsystems that can supply node metadata.
|
|
// The publisher calls Provide() every cycle and stores the result in the peerstore.
|
|
type MetadataProvider interface {
|
|
ProvideMetadata() *RQLiteNodeMetadata
|
|
}
|
|
|
|
// MetadataPublisher periodically writes local node metadata to the peerstore so
|
|
// it is included in every peer exchange response. This decouples metadata
|
|
// production (lifecycle, RQLite status, service health) from the exchange
|
|
// protocol itself.
|
|
type MetadataPublisher struct {
|
|
host host.Host
|
|
provider MetadataProvider
|
|
interval time.Duration
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewMetadataPublisher creates a publisher that writes metadata every interval.
|
|
func NewMetadataPublisher(h host.Host, provider MetadataProvider, interval time.Duration, logger *zap.Logger) *MetadataPublisher {
|
|
if interval <= 0 {
|
|
interval = 10 * time.Second
|
|
}
|
|
return &MetadataPublisher{
|
|
host: h,
|
|
provider: provider,
|
|
interval: interval,
|
|
logger: logger.With(zap.String("component", "metadata-publisher")),
|
|
}
|
|
}
|
|
|
|
// Start begins the periodic publish loop. It blocks until ctx is cancelled.
|
|
func (p *MetadataPublisher) Start(ctx context.Context) {
|
|
// Publish immediately on start
|
|
p.publish()
|
|
|
|
ticker := time.NewTicker(p.interval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
p.publish()
|
|
}
|
|
}
|
|
}
|
|
|
|
// PublishNow performs a single immediate metadata publish.
|
|
// Useful after lifecycle transitions or other state changes.
|
|
func (p *MetadataPublisher) PublishNow() {
|
|
p.publish()
|
|
}
|
|
|
|
func (p *MetadataPublisher) publish() {
|
|
meta := p.provider.ProvideMetadata()
|
|
if meta == nil {
|
|
return
|
|
}
|
|
|
|
data, err := json.Marshal(meta)
|
|
if err != nil {
|
|
p.logger.Error("Failed to marshal metadata", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
if err := p.host.Peerstore().Put(p.host.ID(), "rqlite_metadata", data); err != nil {
|
|
p.logger.Error("Failed to store metadata in peerstore", zap.Error(err))
|
|
}
|
|
}
|