Skip to content

Switch to snappy/proto for encoding ring in consul #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 25, 2016
Merged

Conversation

tomwilkie
Copy link
Contributor

@tomwilkie tomwilkie commented Nov 25, 2016

Fixes #156

(Includes #162 and #161 for now, until they are merged)

  • The ring can read and write json and proto
  • Internal representation is all proto, and there is a translation between the two (ring.go:MarshalJSON)
  • Ingesters will always try to read json first, fallback to proto if that fails
  • Once ingester fails to read json, it will always write proto
  • Ingester will also start writing proto once it has detected all ingesters can read it

Have testing upgrades from master to this locally

@jml jml changed the title Swtich to snappy/proto for encoding ring in consul Switch to snappy/proto for encoding ring in consul Nov 25, 2016
Copy link
Contributor

@jml jml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small change recommended for status page (which looks great, btw).

FWIW, I'd personally have preferred to review these as 3 separate PRs: delete the ingester http client/server; proto; ring status page

<td>{{ $key }}</td>
<td>{{ $value.State }}</td>
<td>{{ $value.Hostname }}</td>
<td>{{ $value.Timestamp | time }}</td>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, this time is from the ingester's clock, but the state is inferred from the distributor's clock.

Either way, this page should either show the distributor's opinion of the current time outside the table (so we have a basis for comparison), or the delta between the current time and the last heartbeat in the table.

@jml jml self-assigned this Nov 25, 2016
@tomwilkie tomwilkie changed the title Switch to snappy/proto for encoding ring in consul [WIP] Switch to snappy/proto for encoding ring in consul Nov 25, 2016
@tomwilkie tomwilkie assigned tomwilkie and unassigned jml Nov 25, 2016
@tomwilkie tomwilkie force-pushed the protoring branch 3 times, most recently from 6bcd711 to e79df77 Compare November 25, 2016 15:21
@tomwilkie tomwilkie changed the title [WIP] Switch to snappy/proto for encoding ring in consul Switch to snappy/proto for encoding ring in consul Nov 25, 2016
@tomwilkie tomwilkie removed their assignment Nov 25, 2016
Copy link
Contributor

@jml jml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM. I really think serdes should be renamed to codec.

// InstanceFactory type creates empty instances for use when deserialising
type InstanceFactory func() interface{}
// SerDes allows the consult client to serialise and deserialise values.
type SerDes interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codec would be a more traditional name, and would be more consistent with the methods on json & proto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:+1

}
return nil

return d.proto.Decode(bytes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The downside of this method is that it will mask genuine JSON errors. A more precise approach would be to figure out exactly which error is returned when we try to decode protobufs as JSON (https://godoc.org/encoding/json has a bunch), and then type assert on that.

I'm not entirely sure it's worth it, though.

return &DynamicSerDes{
useProto: false,
json: json,
proto: proto,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A different approach would be to have a vector of SerDes instead of special json and proto ones, and an index of the currently selected format, instead of useProto. That way this would work with future format changes.

Then the public UseProto would become UseVersion and the check for allIngestersCanReadProtos would instead find the minimum supported version.

Not sure it's worth it though. Would help for future compatibility stuff and for tests (because you could pass much simpler codecs & objects).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it's worth it though.

This. I intend to delete most of this code once we get into production, and I doubt we'll be doing another move like this in the future, at least to the extent where is worth maintaining this code.

if d.useProto {
return d.proto.Encode(msg)
}
return d.json.Encode(msg)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd welcome unit tests for DynamicSerDes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh, I intend to delete it next week.

d.mtx.Lock()
defer d.mtx.Unlock()
d.useProto = useProto
if d.useProto != useProto {
log.Infof("Switching to proto serialization: %v", useProto)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except this isn't true. If useProto is false, then we are switching away from proto encoding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update.


if !d.useProto {
log.Infof("Error decoding json, switching to writing proto: %v", err)
d.useProto = true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jml perhaps I should do this only if d.proto.Decode succeeds?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good thought.

Copy link
Contributor

@jml jml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@@ -165,7 +165,7 @@ func (r *IngesterRegistration) heartbeat(tokens []uint32) {
ingesterDesc.Timestamp = time.Now().Unix()
ingesterDesc.State = r.state

// Set ProtoRing back to true for the case where an existing ingester that didn't understand this field removed it whilst updating the ring.
// Set ProtoRing back to true for the case where an existing ingestser that didn't understand this field removed it whilst updating the ring.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:trollface:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally not seeing if you're paying attention...

@tomwilkie tomwilkie merged commit 79462f9 into master Nov 25, 2016
@tomwilkie tomwilkie deleted the protoring branch November 25, 2016 18:10
tomwilkie added a commit that referenced this pull request Nov 26, 2016
This reverts commit 79462f9, reversing
changes made to dfd6ab2.
tomwilkie added a commit that referenced this pull request Nov 26, 2016
Revert "Merge pull request #159 from weaveworks/protoring"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants