ipfs-cluster/monitor/metrics/store.go
Hector Sanjuan 6447ea51d2 Remove *Serial types. Use pointers for all types.
This takes advantange of the latest features in go-cid, peer.ID and
go-multiaddr and makes the Go types serializable by default.

This means we no longer need to copy between Pin <-> PinSerial, or ID <->
IDSerial etc. We can now efficiently binary-encode these types using short
field keys and without parsing/stringifying (in many cases it just a cast).

We still get the same json output as before (with minor modifications for
Cids).

This should greatly improve Cluster performance and memory usage when dealing
with large collections of items.

License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
2019-02-27 17:04:35 +00:00

93 lines
1.8 KiB
Go

package metrics
import (
"sync"
"github.com/ipfs/ipfs-cluster/api"
peer "github.com/libp2p/go-libp2p-peer"
)
// PeerMetrics maps a peer IDs to a metrics window.
type PeerMetrics map[peer.ID]*Window
// Store can be used to store and access metrics.
type Store struct {
mux sync.RWMutex
byName map[string]PeerMetrics
}
// NewStore can be used to create a Store.
func NewStore() *Store {
return &Store{
byName: make(map[string]PeerMetrics),
}
}
// Add inserts a new metric in Metrics.
func (mtrs *Store) Add(m *api.Metric) {
mtrs.mux.Lock()
defer mtrs.mux.Unlock()
name := m.Name
peer := m.Peer
mbyp, ok := mtrs.byName[name]
if !ok {
mbyp = make(PeerMetrics)
mtrs.byName[name] = mbyp
}
window, ok := mbyp[peer]
if !ok {
// We always lock the outer map, so we can use unsafe
// Window.
window = NewWindow(DefaultWindowCap)
mbyp[peer] = window
}
window.Add(m)
}
// Latest returns all the last known valid metrics. A metric is valid
// if it has not expired.
func (mtrs *Store) Latest(name string) []*api.Metric {
mtrs.mux.RLock()
defer mtrs.mux.RUnlock()
byPeer, ok := mtrs.byName[name]
if !ok {
return []*api.Metric{}
}
metrics := make([]*api.Metric, 0, len(byPeer))
for _, window := range byPeer {
m, err := window.Latest()
if err != nil || m.Discard() {
continue
}
metrics = append(metrics, m)
}
return metrics
}
// PeerMetrics returns the latest metrics for a given peer ID for
// all known metrics types. It may return expired metrics.
func (mtrs *Store) PeerMetrics(pid peer.ID) []*api.Metric {
mtrs.mux.RLock()
defer mtrs.mux.RUnlock()
result := make([]*api.Metric, 0)
for _, byPeer := range mtrs.byName {
window, ok := byPeer[pid]
if !ok {
continue
}
metric, err := window.Latest()
if err != nil {
continue
}
result = append(result, metric)
}
return result
}