Use github.com/ugorji/go/codec/ for wiring messages

* New encoding format:
  * Msgpack reports between probe<->app (smaller representation, faster to
    encode/decode).
  * Still use JSON between app<->UI (try to avoid making javascript deal with
    mspack).

  The app still suports publishing reports in both gob and JSON, not braking
  backwards compatibility.

* Use compile-time generated marshallers/unmarshallers for higher performance. In
  order to be able to skip code-generation for certain types, I included
  https://github.com/2opremio/go-1/tree/master/codec/codecgen instead of
  upstream until https://github.com/ugorji/go/pull/139 is merged.

* Encode/decode intermediate types using github.com/ugorji/go/codec.Selfer
  for higher performance and reducing garbage collection (no temporary buffers).
This commit is contained in:
Alfonso Acosta
2016-02-04 15:22:55 +00:00
parent 3b56244c90
commit 0d917b2d8b
80 changed files with 57055 additions and 242 deletions

View File

@@ -1,11 +1,12 @@
package render_test
import (
"encoding/json"
"flag"
"io/ioutil"
"testing"
"github.com/ugorji/go/codec"
"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test/fixture"
@@ -94,6 +95,6 @@ func loadReport() (report.Report, error) {
return rpt, err
}
rpt := report.MakeReport()
err = json.Unmarshal(b, &rpt)
err = codec.NewDecoderBytes(b, &codec.JsonHandle{}).Decode(&rpt)
return rpt, err
}

View File

@@ -1,10 +1,12 @@
package detailed
import (
"encoding/json"
"bytes"
"strconv"
"strings"
"github.com/ugorji/go/codec"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/probe/kubernetes"
@@ -120,7 +122,9 @@ func (m MetadataRow) Copy() MetadataRow {
// MarshalJSON marshals this MetadataRow to json. It adds a label before
// rendering.
func (m MetadataRow) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
buf := bytes.Buffer{}
encoder := codec.NewEncoder(&buf, &codec.JsonHandle{})
err := encoder.Encode(struct {
ID string `json:"id"`
Label string `json:"label"`
Value string `json:"value"`
@@ -131,6 +135,7 @@ func (m MetadataRow) MarshalJSON() ([]byte, error) {
Value: m.Value,
Prime: m.Prime,
})
return buf.Bytes(), err
}
// NodeMetadata produces a table (to be consumed directly by the UI) based on

View File

@@ -1,9 +1,10 @@
package detailed
import (
"encoding/json"
"bytes"
"math"
"github.com/ugorji/go/codec"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/probe/process"
@@ -62,7 +63,9 @@ func (m MetricRow) Copy() MetricRow {
// MarshalJSON marshals this MetricRow to json. It takes the basic Metric
// rendering, then adds some row-specific fields.
func (m MetricRow) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
buf := bytes.Buffer{}
encoder := codec.NewEncoder(&buf, &codec.JsonHandle{})
err := encoder.Encode(struct {
ID string `json:"id"`
Label string `json:"label"`
Format string `json:"format,omitempty"`
@@ -77,6 +80,7 @@ func (m MetricRow) MarshalJSON() ([]byte, error) {
Value: m.Value,
WireMetrics: m.Metric.ToIntermediate(),
})
return buf.Bytes(), err
}
// NodeMetrics produces a table (to be consumed directly by the UI) based on

View File

@@ -1,9 +1,10 @@
package detailed
import (
"encoding/json"
"fmt"
"github.com/ugorji/go/codec"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/probe/kubernetes"
@@ -37,19 +38,27 @@ func (g NodeSummaryGroup) Copy() NodeSummaryGroup {
// their label for the frontend.
type Column string
// MarshalJSON serializes a column to json
func (c Column) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]string{"id": string(c), "label": Label(string(c))})
// CodecEncodeSelf implements codec.Selfer
func (c *Column) CodecEncodeSelf(encoder *codec.Encoder) {
in := map[string]string{"id": string(*c), "label": Label(string(*c))}
encoder.Encode(in)
}
// UnmarshalJSON deserializes a column from json
func (c *Column) UnmarshalJSON(b []byte) error {
// CodecDecodeSelf implements codec.Selfer
func (c *Column) CodecDecodeSelf(decoder *codec.Decoder) {
m := map[string]string{}
if err := json.Unmarshal(b, &m); err != nil {
return err
}
decoder.Decode(&m)
*c = Column(m["id"])
return nil
}
// MarshalJSON shouldn't be used, use CodecEncodeSelf instead
func (Column) MarshalJSON() ([]byte, error) {
panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead")
}
// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead
func (*Column) UnmarshalJSON(b []byte) error {
panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead")
}
// NodeSummary is summary information about a child for a Node.