add WidgetUpdater interface to container, replace struct fields with metamap

This commit is contained in:
Bradley Cicenas
2017-03-06 08:25:59 +00:00
parent e1dc42db03
commit f102e48cc9
8 changed files with 48 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"github.com/bcicen/ctop/cwidgets"
"github.com/bcicen/ctop/cwidgets/compact" "github.com/bcicen/ctop/cwidgets/compact"
"github.com/bcicen/ctop/metrics" "github.com/bcicen/ctop/metrics"
) )
@@ -9,25 +10,36 @@ import (
type Container struct { type Container struct {
metrics.Metrics metrics.Metrics
Id string Id string
Name string
State string
Meta map[string]string Meta map[string]string
Updates chan [2]string
Widgets *compact.Compact Widgets *compact.Compact
updater cwidgets.WidgetUpdater
collector metrics.Collector collector metrics.Collector
} }
func NewContainer(id string, collector metrics.Collector) *Container { func NewContainer(id string, collector metrics.Collector) *Container {
widgets := compact.NewCompact(id)
return &Container{ return &Container{
Metrics: metrics.NewMetrics(), Metrics: metrics.NewMetrics(),
Id: id, Id: id,
Meta: make(map[string]string), Meta: make(map[string]string),
Updates: make(chan [2]string), Widgets: widgets,
Widgets: compact.NewCompact(id), updater: widgets,
collector: collector, collector: collector,
} }
} }
func (c *Container) SetUpdater(u cwidgets.WidgetUpdater) {
c.updater = u
for k, v := range c.Meta {
c.updater.SetMeta(k, v)
}
}
func (c *Container) SetMeta(k, v string) {
c.Meta[k] = v
c.updater.SetMeta(k, v)
}
func (c *Container) GetMeta(k string) string { func (c *Container) GetMeta(k string) string {
if v, ok := c.Meta[k]; ok { if v, ok := c.Meta[k]; ok {
return v return v
@@ -35,26 +47,15 @@ func (c *Container) GetMeta(k string) string {
return "" return ""
} }
func (c *Container) SetMeta(k, v string) {
c.Meta[k] = v
c.Updates <- [2]string{k, v}
}
func (c *Container) SetName(n string) {
c.Name = n
c.Widgets.Name.Set(n)
}
func (c *Container) SetState(s string) { func (c *Container) SetState(s string) {
c.State = s c.SetMeta("state", s)
c.Widgets.Status.Set(s)
// start collector, if needed // start collector, if needed
if c.State == "running" && !c.collector.Running() { if s == "running" && !c.collector.Running() {
c.collector.Start() c.collector.Start()
c.Read(c.collector.Stream()) c.Read(c.collector.Stream())
} }
// stop collector, if needed // stop collector, if needed
if c.State != "running" && c.collector.Running() { if s != "running" && c.collector.Running() {
c.collector.Stop() c.collector.Stop()
} }
} }
@@ -64,7 +65,7 @@ func (c *Container) Read(stream chan metrics.Metrics) {
go func() { go func() {
for metrics := range stream { for metrics := range stream {
c.Metrics = metrics c.Metrics = metrics
c.Widgets.SetMetrics(metrics) c.updater.SetMetrics(metrics)
} }
log.Infof("reader stopped for container: %s", c.Id) log.Infof("reader stopped for container: %s", c.Id)
c.Metrics = metrics.NewMetrics() c.Metrics = metrics.NewMetrics()

View File

@@ -46,6 +46,15 @@ func NewCompact(id string) *Compact {
//} //}
//} //}
func (row *Compact) SetMeta(k, v string) {
switch k {
case "name":
row.Name.Set(v)
case "state":
row.Status.Set(v)
}
}
func (row *Compact) SetMetrics(m metrics.Metrics) { func (row *Compact) SetMetrics(m metrics.Metrics) {
row.SetCPU(m.CPUUtil) row.SetCPU(m.CPUUtil)
row.SetNet(m.NetRx, m.NetTx) row.SetNet(m.NetRx, m.NetTx)

View File

@@ -2,19 +2,12 @@ package cwidgets
import ( import (
"github.com/bcicen/ctop/logging" "github.com/bcicen/ctop/logging"
ui "github.com/gizak/termui" "github.com/bcicen/ctop/metrics"
) )
var log = logging.Init() var log = logging.Init()
type ContainerWidgets interface { type WidgetUpdater interface {
Buffer() ui.Buffer SetMeta(string, string)
Highlight() SetMetrics(metrics.Metrics)
UnHighlight()
SetY(int)
SetWidth(int)
SetStatus(string)
SetCPU(int)
SetNet(int64, int64)
SetMem(int64, int64, int)
} }

View File

@@ -21,7 +21,9 @@ func logEvent(e ui.Event) {
// log container, metrics, and widget state // log container, metrics, and widget state
func dumpContainer(c *Container) { func dumpContainer(c *Container) {
msg := fmt.Sprintf("logging state for container: %s\n", c.Id) msg := fmt.Sprintf("logging state for container: %s\n", c.Id)
msg += fmt.Sprintf("Id = %s\nname = %s\nstate = %s\n", c.Id, c.Name, c.State) for k, v := range c.Meta {
msg += fmt.Sprintf("Meta.%s = %s\n", k, v)
}
msg += inspect(&c.Metrics) msg += inspect(&c.Metrics)
log.Infof(msg) log.Infof(msg)
} }

View File

@@ -65,7 +65,7 @@ func (cm *DockerContainerSource) refresh(c *Container) {
cm.delByID(c.Id) cm.delByID(c.Id)
return return
} }
c.SetName(shortName(insp.Name)) c.SetMeta("name", shortName(insp.Name))
c.SetState(insp.State.Status) c.SetState(insp.State.Status)
} }
@@ -89,7 +89,7 @@ func (cm *DockerContainerSource) refreshAll() {
for _, i := range allContainers { for _, i := range allContainers {
c := cm.MustGet(i.ID) c := cm.MustGet(i.ID)
c.SetName(shortName(i.Names[0])) c.SetMeta("name", shortName(i.Names[0]))
c.SetState(i.State) c.SetState(i.State)
cm.needsRefresh <- c.Id cm.needsRefresh <- c.Id
} }

View File

@@ -1,8 +1,6 @@
package main package main
import ( import (
"fmt"
"github.com/bcicen/ctop/config" "github.com/bcicen/ctop/config"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )

View File

@@ -31,7 +31,7 @@ func (cs *MockContainerSource) Init() {
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
collector := metrics.NewMock() collector := metrics.NewMock()
c := NewContainer(makeID(), collector) c := NewContainer(makeID(), collector)
c.SetName(makeName()) c.SetMeta("name", makeName())
c.SetState(makeState()) c.SetState(makeState())
cs.containers = append(cs.containers, c) cs.containers = append(cs.containers, c)
} }

13
sort.go
View File

@@ -14,10 +14,11 @@ var stateMap = map[string]int{
"paused": 2, "paused": 2,
"exited": 1, "exited": 1,
"created": 0, "created": 0,
"": 0,
} }
var idSorter = func(c1, c2 *Container) bool { return c1.Id < c2.Id } var idSorter = func(c1, c2 *Container) bool { return c1.Id < c2.Id }
var nameSorter = func(c1, c2 *Container) bool { return c1.Name < c2.Name } var nameSorter = func(c1, c2 *Container) bool { return c1.GetMeta("name") < c2.GetMeta("name") }
var Sorters = map[string]sortMethod{ var Sorters = map[string]sortMethod{
"id": idSorter, "id": idSorter,
@@ -54,10 +55,12 @@ var Sorters = map[string]sortMethod{
}, },
"state": func(c1, c2 *Container) bool { "state": func(c1, c2 *Container) bool {
// Use secondary sort method if equal values // Use secondary sort method if equal values
if c1.State == c2.State { c1state := c1.GetMeta("state")
c2state := c2.GetMeta("state")
if c1state == c2state {
return nameSorter(c1, c2) return nameSorter(c1, c2)
} }
return stateMap[c1.State] > stateMap[c2.State] return stateMap[c1state] > stateMap[c2state]
}, },
} }
@@ -86,11 +89,11 @@ func (a Containers) Filter() (filtered []*Container) {
for _, c := range a { for _, c := range a {
// Apply name filter // Apply name filter
if re.FindAllString(c.Name, 1) == nil { if re.FindAllString(c.GetMeta("name"), 1) == nil {
continue continue
} }
// Apply state filter // Apply state filter
if !config.GetSwitchVal("allContainers") && c.State != "running" { if !config.GetSwitchVal("allContainers") && c.GetMeta("state") != "running" {
continue continue
} }
filtered = append(filtered, c) filtered = append(filtered, c)