mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
Ensure backward compatilibity in report's node controls
The new probe will convert all node's LatestControls to Controls, so the old app can consume them. Also, the new app will convert all node's Controls to LatestControl, so it can consume the reports from old probes.
This commit is contained in:
@@ -118,7 +118,9 @@ func (c *collector) Report(_ context.Context) (report.Report, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.clean()
|
c.clean()
|
||||||
return c.merger.Merge(c.reports), nil
|
rpt := c.merger.Merge(c.reports).Upgrade()
|
||||||
|
c.cached = &rpt
|
||||||
|
return rpt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) clean() {
|
func (c *collector) clean() {
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ ForLoop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.publisher.Publish(rpt); err != nil {
|
if err := p.publisher.Publish(rpt.BackwardCompatible()); err != nil {
|
||||||
log.Infof("publish: %v", err)
|
log.Infof("publish: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/weaveworks/scope/common/mtime"
|
||||||
"github.com/weaveworks/scope/common/xfer"
|
"github.com/weaveworks/scope/common/xfer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -254,6 +255,57 @@ func (r Report) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upgrade returns a new report based on a report received from the old probe.
|
||||||
|
//
|
||||||
|
// This for now creates node's LatestControls from Controls.
|
||||||
|
func (r Report) Upgrade() Report {
|
||||||
|
cp := r.Copy()
|
||||||
|
ncd := NodeControlData{
|
||||||
|
Dead: false,
|
||||||
|
}
|
||||||
|
cp.WalkTopologies(func(topology *Topology) {
|
||||||
|
n := Nodes{}
|
||||||
|
for name, node := range topology.Nodes {
|
||||||
|
if node.LatestControls.Size() == 0 && len(node.Controls.Controls) > 0 {
|
||||||
|
for _, control := range node.Controls.Controls {
|
||||||
|
node.LatestControls = node.LatestControls.Set(control, node.Controls.Timestamp, ncd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n[name] = node
|
||||||
|
}
|
||||||
|
topology.Nodes = n
|
||||||
|
})
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// BackwardCompatible returns a new backward-compatible report.
|
||||||
|
//
|
||||||
|
// This for now creates node's Controls from LatestControls.
|
||||||
|
func (r Report) BackwardCompatible() Report {
|
||||||
|
now := mtime.Now()
|
||||||
|
cp := r.Copy()
|
||||||
|
cp.WalkTopologies(func(topology *Topology) {
|
||||||
|
n := Nodes{}
|
||||||
|
for name, node := range topology.Nodes {
|
||||||
|
var controls []string
|
||||||
|
node.LatestControls.ForEach(func(k string, _ time.Time, v NodeControlData) {
|
||||||
|
if !v.Dead {
|
||||||
|
controls = append(controls, k)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if len(controls) > 0 {
|
||||||
|
node.Controls = NodeControls{
|
||||||
|
Timestamp: now,
|
||||||
|
Controls: MakeStringSet(controls...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n[name] = node
|
||||||
|
}
|
||||||
|
topology.Nodes = n
|
||||||
|
})
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
// Sampling describes how the packet data sources for this report were
|
// Sampling describes how the packet data sources for this report were
|
||||||
// sampled. It can be used to calculate effective sample rates. We can't
|
// sampled. It can be used to calculate effective sample rates. We can't
|
||||||
// just put the rate here, because that can't be accurately merged. Counts
|
// just put the rate here, because that can't be accurately merged. Counts
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ package report_test
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/weaveworks/scope/common/mtime"
|
||||||
"github.com/weaveworks/scope/report"
|
"github.com/weaveworks/scope/report"
|
||||||
|
"github.com/weaveworks/scope/test"
|
||||||
|
s_reflect "github.com/weaveworks/scope/test/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newu64(value uint64) *uint64 { return &value }
|
func newu64(value uint64) *uint64 { return &value }
|
||||||
@@ -74,3 +78,46 @@ func TestNode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReportBackwardCompatibility(t *testing.T) {
|
||||||
|
mtime.NowForce(time.Now())
|
||||||
|
defer mtime.NowReset()
|
||||||
|
rpt := report.MakeReport()
|
||||||
|
controls := map[string]report.NodeControlData{
|
||||||
|
"dead": {
|
||||||
|
Dead: true,
|
||||||
|
},
|
||||||
|
"alive": {
|
||||||
|
Dead: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
node := report.MakeNode("foo").WithLatestControls(controls)
|
||||||
|
expectedNode := node.WithControls("alive")
|
||||||
|
rpt.Pod.AddNode(node)
|
||||||
|
expected := report.MakeReport()
|
||||||
|
expected.Pod.AddNode(expectedNode)
|
||||||
|
got := rpt.BackwardCompatible()
|
||||||
|
if !s_reflect.DeepEqual(expected, got) {
|
||||||
|
t.Error(test.Diff(expected, got))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReportUpgrade(t *testing.T) {
|
||||||
|
mtime.NowForce(time.Now())
|
||||||
|
defer mtime.NowReset()
|
||||||
|
node := report.MakeNode("foo").WithControls("alive")
|
||||||
|
controls := map[string]report.NodeControlData{
|
||||||
|
"alive": {
|
||||||
|
Dead: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expectedNode := node.WithLatestControls(controls)
|
||||||
|
rpt := report.MakeReport()
|
||||||
|
rpt.Pod.AddNode(node)
|
||||||
|
expected := report.MakeReport()
|
||||||
|
expected.Pod.AddNode(expectedNode)
|
||||||
|
got := rpt.Upgrade()
|
||||||
|
if !s_reflect.DeepEqual(expected, got) {
|
||||||
|
t.Error(test.Diff(expected, got))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user