2512ecb701
New PeerManager, Allocator, Informer components have been added along with a new "replication_factor" configuration option. First, cluster peers collect and push metrics (Informer) to the Cluster leader regularly. The Informer is an interface that can be implemented in custom wayts to support custom metrics. Second, on a pin operation, using the information from the collected metrics, an Allocator can provide a list of preferences as to where the new pin should be assigned. The Allocator is an interface allowing to provide different allocation strategies. Both Allocator and Informer are Cluster Componenets, and have access to the RPC API. The allocations are kept in the shared state. Cluster peer failure detection is still missing and re-allocation is still missing, although re-pinning something when a node is down/metrics missing does re-allocate the pin somewhere else. License: MIT Signed-off-by: Hector Sanjuan <hector@protocol.ai>
78 lines
1.7 KiB
Go
78 lines
1.7 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 (
|
|
"fmt"
|
|
|
|
rpc "github.com/hsanjuan/go-libp2p-gorpc"
|
|
|
|
"github.com/ipfs/ipfs-cluster/api"
|
|
)
|
|
|
|
// MetricTTL specifies how long our reported metric is valid in seconds.
|
|
var MetricTTL = 10
|
|
|
|
// MetricName specifies the name of our metric
|
|
var MetricName = "numpin"
|
|
|
|
// Informer is a simple object to implement the ipfscluster.Informer
|
|
// and Component interfaces
|
|
type Informer struct {
|
|
rpcClient *rpc.Client
|
|
}
|
|
|
|
func NewInformer() *Informer {
|
|
return &Informer{}
|
|
}
|
|
|
|
// 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() error {
|
|
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() api.Metric {
|
|
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.Call("", // Local call
|
|
"Cluster", // Service name
|
|
"IPFSPinLs", // 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(MetricTTL)
|
|
return m
|
|
}
|