freespace metric partial impl

This commit is contained in:
dgrisham 2017-08-02 16:49:25 -06:00
parent b911aa7bdc
commit a46ab3dda9
7 changed files with 59 additions and 10 deletions

View File

@ -79,6 +79,7 @@ func (ipfs *mockConnector) PinLs(filter string) (map[string]api.IPFSPinStatus, e
func (ipfs *mockConnector) ConnectSwarms() error { return nil }
func (ipfs *mockConnector) ConfigKey(keypath string) (interface{}, error) { return nil, nil }
func (ipfs *mockConnector) FreeSpace() (int, error) { return 0, nil }
func (ipfs *mockConnector) RepoSize() (int, error) { return 0, nil }
func testingCluster(t *testing.T) (*Cluster, *mockAPI, *mockConnector, *mapstate.MapState, *maptracker.MapPinTracker) {

View File

@ -12,13 +12,21 @@ import (
"github.com/ipfs/ipfs-cluster/api"
)
// TODO: switch default to disk-freespace
const DefaultMetric = "disk-reposize"
var logger = logging.Logger("diskinfo")
// MetricTTL specifies how long our reported metric is valid in seconds.
var MetricTTL = 30
// MetricName specifies the name of our metric
var MetricName = "disk"
var MetricName string
var nameToRPC = map[string]string{
"disk-freespace": "IPFSFreeSpace",
"disk-reposize": "IPFSRepoSize",
}
// Informer is a simple object to implement the ipfscluster.Informer
// and Component interfaces.
@ -28,6 +36,14 @@ type Informer struct {
// NewInformer returns an initialized Informer.
func NewInformer() *Informer {
MetricName = DefaultMetric
return &Informer{}
}
// NewInformer returns an initialized Informer.
func NewInformerWithMetric(metric string) *Informer {
// assume `metric` has been checked already
MetricName = metric
return &Informer{}
}
@ -49,8 +65,6 @@ func (disk *Informer) Name() string {
return MetricName
}
// GetMetric uses the IPFSConnector the current
// repository size and returns it in a metric.
func (disk *Informer) GetMetric() api.Metric {
if disk.rpcClient == nil {
return api.Metric{
@ -58,13 +72,13 @@ func (disk *Informer) GetMetric() api.Metric {
}
}
var repoSize int
var metric int
valid := true
err := disk.rpcClient.Call("",
"Cluster",
"IPFSRepoSize",
nameToRPC[MetricName],
struct{}{},
&repoSize)
&metric)
if err != nil {
logger.Error(err)
valid = false
@ -72,7 +86,7 @@ func (disk *Informer) GetMetric() api.Metric {
m := api.Metric{
Name: MetricName,
Value: fmt.Sprintf("%d", repoSize),
Value: fmt.Sprintf("%d", metric),
Valid: valid,
}

View File

@ -52,7 +52,7 @@ func (mock *badRPCService) IPFSRepoSize(in struct{}, out *int) error {
func Test(t *testing.T) {
inf := NewInformer()
defer inf.Shutdown()
if inf.Name() != "disk" {
if inf.Name() != DefaultMetric {
t.Error("careful when changing the name of an informer")
}
m := inf.GetMetric()

View File

@ -342,8 +342,12 @@ func setupLogging(lvl string) {
func setupAllocation(strategy string) (ipfscluster.Informer, ipfscluster.PinAllocator) {
switch strategy {
case "disk", "reposize":
return disk.NewInformer(), ascendalloc.NewAllocator()
case "disk":
informer := disk.NewInformer()
return informer, ascendalloc.NewAllocator()
case "disk-freespace", "disk-reposize":
informer := disk.NewInformerWithMetric(strategy)
return informer, ascendalloc.NewAllocator()
case "numpin", "pincount":
return numpin.NewInformer(), ascendalloc.NewAllocator()
default:

View File

@ -77,6 +77,9 @@ type IPFSConnector interface {
// ConfigKey returns the value for a configuration key.
// Subobjects are reached with keypaths as "Parent/Child/GrandChild...".
ConfigKey(keypath string) (interface{}, error)
// FreeSpace returns the amount of remaining space on the repo, calculated from
//"repo stat"
FreeSpace() (int, error)
// RepoSize returns the current repository size as expressed
// by "repo stat".
RepoSize() (int, error)

View File

@ -101,6 +101,7 @@ type ipfsIDResp struct {
type ipfsRepoStatResp struct {
RepoSize int
StorageMax int
NumObjects int
}
@ -811,6 +812,25 @@ func getConfigValue(path []string, cfg map[string]interface{}) (interface{}, err
}
}
// FreeSpace returns the amount of unused space in the ipfs repository. This
// value is derived from the RepoSize and StorageMax values given by "repo
// stats". The value is in bytes.
func (ipfs *Connector) FreeSpace() (int, error) {
res, err := ipfs.get("repo/stat")
if err != nil {
logger.Error(err)
return 0, err
}
var stats ipfsRepoStatResp
err = json.Unmarshal(res, &stats)
if err != nil {
logger.Error(err)
return 0, err
}
return stats.StorageMax - stats.RepoSize, nil
}
// RepoSize returns the current repository size of the ipfs daemon as
// provided by "repo stats". The value is in bytes.
func (ipfs *Connector) RepoSize() (int, error) {

View File

@ -242,6 +242,13 @@ func (rpcapi *RPCAPI) IPFSConfigKey(in string, out *interface{}) error {
return err
}
// IPFSFreeSpace runs IPFSConnector.FreeSpace().
func (rpcapi *RPCAPI) IPFSFreeSpace(in struct{}, out *int) error {
res, err := rpcapi.c.ipfs.FreeSpace()
*out = res
return err
}
// IPFSRepoSize runs IPFSConnector.RepoSize().
func (rpcapi *RPCAPI) IPFSRepoSize(in struct{}, out *int) error {
res, err := rpcapi.c.ipfs.RepoSize()