mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 09:41:57 +00:00
Add benchmark for list topologies API.
This commit is contained in:
@@ -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
|
||||
|
||||
55
app/benchmark_internal_test.go
Normal file
55
app/benchmark_internal_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user