Add benchmark for list topologies API.

This commit is contained in:
Tom Wilkie
2016-01-25 15:05:48 -08:00
parent b1a3a15ac0
commit 0e3e3b74f8
3 changed files with 71 additions and 24 deletions

View File

@@ -189,23 +189,25 @@ func (r *registry) walk(f func(APITopologyDesc)) {
// makeTopologyList returns a handler that yields an APITopologyList.
func (r *registry) makeTopologyList(rep Reporter) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
var (
rpt = rep.Report()
topologies = []APITopologyDesc{}
)
r.walk(func(desc APITopologyDesc) {
renderer := renderedForRequest(req, desc)
desc.Stats = decorateWithStats(rpt, renderer)
for i := range desc.SubTopologies {
renderer := renderedForRequest(req, desc.SubTopologies[i])
desc.SubTopologies[i].Stats = decorateWithStats(rpt, renderer)
}
topologies = append(topologies, desc)
})
topologies := r.renderTopologies(rep.Report(), req)
respondWith(w, http.StatusOK, topologies)
}
}
func (r *registry) renderTopologies(rpt report.Report, req *http.Request) []APITopologyDesc {
topologies := []APITopologyDesc{}
r.walk(func(desc APITopologyDesc) {
renderer := renderedForRequest(req, desc)
desc.Stats = decorateWithStats(rpt, renderer)
for i := range desc.SubTopologies {
renderer := renderedForRequest(req, desc.SubTopologies[i])
desc.SubTopologies[i].Stats = decorateWithStats(rpt, renderer)
}
topologies = append(topologies, desc)
})
return topologies
}
func decorateWithStats(rpt report.Report, renderer render.Renderer) topologyStats {
var (
nodes int

View File

@@ -0,0 +1,55 @@
package app
import (
"encoding/json"
"flag"
"io/ioutil"
"net/http"
"net/url"
"testing"
"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test/fixture"
)
// StaticReport is used as a fixture in tests. It emulates an xfer.Collector.
type StaticReporter struct{ r report.Report }
func (s StaticReporter) Report() report.Report { return s.r }
func (s StaticReporter) WaitOn(chan struct{}) {}
func (s StaticReporter) UnWait(chan struct{}) {}
var (
benchReportFile = flag.String("bench-report-file", "", "json report file to use for benchmarking (relative to this package)")
)
func loadReport() (report.Report, error) {
if *benchReportFile == "" {
return fixture.Report, nil
}
b, err := ioutil.ReadFile(*benchReportFile)
if err != nil {
return fixture.Report, err
}
rpt := report.MakeReport()
err = json.Unmarshal(b, &rpt)
return rpt, err
}
func BenchmarkTopologyList(b *testing.B) {
report, err := loadReport()
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
request := &http.Request{
Form: url.Values{},
}
for i := 0; i < b.N; i++ {
render.ResetCache()
topologyRegistry.renderTopologies(report, request)
}
}

View File

@@ -3,7 +3,6 @@ package render
import (
"fmt"
"reflect"
"strings"
"github.com/bluele/gcache"
@@ -11,34 +10,25 @@ import (
)
var renderCache = gcache.New(100).LRU().Build()
var depth = 0
func memoisedRender(r Renderer, rpt report.Report) RenderableNodes {
fmt.Printf("%sRendering: %#v\n", strings.Repeat(" ", depth), r)
key := ""
v := reflect.ValueOf(r)
switch v.Kind() {
case reflect.Ptr, reflect.Func:
key = fmt.Sprintf("%s-%x", rpt.ID, v.Pointer())
default:
fmt.Printf("%s- Cannot memoise: %v\n", strings.Repeat(" ", depth), r)
return r.Render(rpt)
}
if result, err := renderCache.Get(key); err == nil {
fmt.Printf("%s- Hit %s\n", strings.Repeat(" ", depth), key)
return result.(RenderableNodes)
}
fmt.Printf("%s- Miss %s\n", strings.Repeat(" ", depth), key)
depth += 1
output := r.Render(rpt)
depth -= 1
renderCache.Set(key, output)
return output
}
// ResetCache blows away the rendered node cache.
func ResetCache() {
renderCache.Purge()
}