performance: Send active controls as a single string per node

Instead of a whole extra data structure which is quite expensive to
marshal and unmarshal, just send the information in a string.  No
clever merging strategy is required - the states are all set in one
place per node type.
This commit is contained in:
Bryan Boreham
2019-10-14 15:31:34 +00:00
parent 83f9d4ec8d
commit 0b641b1848
9 changed files with 64 additions and 362 deletions

View File

@@ -389,20 +389,18 @@ func (c *container) getBaseNode() report.Node {
return result
}
func (c *container) controlsMap() map[string]report.NodeControlData {
// Return a slice including all controls that should be shown on this container
func (c *container) controls() []string {
paused := c.container.State.Paused
running := !paused && c.container.State.Running
stopped := !paused && !running
return map[string]report.NodeControlData{
UnpauseContainer: {Dead: !paused},
RestartContainer: {Dead: !running},
StopContainer: {Dead: !running},
PauseContainer: {Dead: !running},
AttachContainer: {Dead: !running},
ExecContainer: {Dead: !running},
StartContainer: {Dead: !stopped},
RemoveContainer: {Dead: !stopped},
switch {
case paused:
return []string{UnpauseContainer}
case c.container.State.Running:
return []string{RestartContainer, StopContainer, PauseContainer, AttachContainer, ExecContainer}
case !c.container.State.Running:
return []string{StartContainer, RemoveContainer}
}
return nil
}
func (c *container) GetNode() report.Node {
@@ -413,7 +411,6 @@ func (c *container) GetNode() report.Node {
ContainerState: c.StateString(),
ContainerStateHuman: c.State(),
}
controls := c.controlsMap()
if !c.container.State.Paused && c.container.State.Running {
uptimeSeconds := int(mtime.Now().Sub(c.container.State.StartedAt) / time.Second)
@@ -427,7 +424,7 @@ func (c *container) GetNode() report.Node {
}
result := c.baseNode.WithLatests(latest)
result = result.WithLatestControls(controls)
result = result.WithLatestActiveControls(c.controls()...)
result = result.WithMetrics(c.metrics())
return result
}

View File

@@ -60,15 +60,12 @@ func TestContainer(t *testing.T) {
// Now see if we go them
{
uptimeSeconds := int(now.Sub(startTime) / time.Second)
controls := map[string]report.NodeControlData{
docker.UnpauseContainer: {Dead: true},
docker.RestartContainer: {Dead: false},
docker.StopContainer: {Dead: false},
docker.PauseContainer: {Dead: false},
docker.AttachContainer: {Dead: false},
docker.ExecContainer: {Dead: false},
docker.StartContainer: {Dead: true},
docker.RemoveContainer: {Dead: true},
controls := []string{
docker.RestartContainer,
docker.StopContainer,
docker.PauseContainer,
docker.AttachContainer,
docker.ExecContainer,
}
want := report.MakeNodeWith("ping;<container>", map[string]string{
"docker_container_command": "ping foo.bar.local",
@@ -82,8 +79,8 @@ func TestContainer(t *testing.T) {
"docker_container_state_human": c.Container().State.String(),
"docker_container_uptime": strconv.Itoa(uptimeSeconds),
"docker_env_FOO": "secret-bar",
}).WithLatestControls(
controls,
}).WithLatestActiveControls(
controls...,
).WithMetrics(report.Metrics{
"docker_cpu_total_usage": report.MakeMetric(nil),
"docker_memory_usage": report.MakeSingletonMetric(now, 12345).WithMax(45678),