ipfs-cluster/informer/numpin/numpin.go
Hector Sanjuan b6a46cd8a4 allocator: rework the whole allocator system
The new "metrics" allocator is about to partition metrics and distribe
allocations among the partitions.

For example: given a region, an availability zone and free space on disk, the
allocator would be able to choose allocations by distributing among regions
and availability zones as much as possible, and for those peers in the same
region/az, selecting those with most free space first.

This requires a major overhaul of the allocator component.
2021-09-13 12:24:00 +02:00

102 lines
2.3 KiB
Go

// Package numpin implements an ipfs-cluster informer which determines how many
// items this peer is pinning and returns it as api.Metric
package numpin
import (
"context"
"fmt"
"github.com/ipfs/ipfs-cluster/allocator/metrics"
"github.com/ipfs/ipfs-cluster/allocator/sorter"
"github.com/ipfs/ipfs-cluster/api"
rpc "github.com/libp2p/go-libp2p-gorpc"
"go.opencensus.io/trace"
)
// MetricName specifies the name of our metric
var MetricName = "numpin"
func init() {
metrics.RegisterInformer(MetricName, sorter.SortNumeric, false)
}
// Informer is a simple object to implement the ipfscluster.Informer
// and Component interfaces
type Informer struct {
config *Config
rpcClient *rpc.Client
}
// NewInformer returns an initialized Informer.
func NewInformer(cfg *Config) (*Informer, error) {
err := cfg.Validate()
if err != nil {
return nil, err
}
return &Informer{
config: cfg,
}, nil
}
// SetClient provides us with an rpc.Client which allows
// contacting other components in the cluster.
func (npi *Informer) SetClient(c *rpc.Client) {
npi.rpcClient = c
}
// Shutdown is called on cluster shutdown. We just invalidate
// any metrics from this point.
func (npi *Informer) Shutdown(ctx context.Context) error {
_, span := trace.StartSpan(ctx, "informer/numpin/Shutdown")
defer span.End()
npi.rpcClient = nil
return nil
}
// Name returns the name of this informer
func (npi *Informer) Name() string {
return MetricName
}
// GetMetric contacts the IPFSConnector component and
// requests the `pin ls` command. We return the number
// of pins in IPFS.
func (npi *Informer) GetMetric(ctx context.Context) *api.Metric {
ctx, span := trace.StartSpan(ctx, "informer/numpin/GetMetric")
defer span.End()
if npi.rpcClient == nil {
return &api.Metric{
Valid: false,
}
}
pinMap := make(map[string]api.IPFSPinStatus)
// make use of the RPC API to obtain information
// about the number of pins in IPFS. See RPCAPI docs.
err := npi.rpcClient.CallContext(
ctx,
"", // Local call
"IPFSConnector", // Service name
"PinLs", // Method name
"recursive", // in arg
&pinMap, // out arg
)
valid := err == nil
m := &api.Metric{
Name: MetricName,
Value: fmt.Sprintf("%d", len(pinMap)),
Valid: valid,
}
m.SetTTL(npi.config.MetricTTL)
return m
}