Skip to content
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

[Feature] Identity carry over part 5 / Multi ring checksum #192

Merged
merged 75 commits into from
Dec 19, 2016

Conversation

thanodnl
Copy link
Contributor

This PR is part 5 for identity carry over.

In this PR a new mechanism for calculating ring checksums is added. It aims to be forward compatible by naming checksums after the algorithm used so that new algorithms can be added and old algorithms can be removed when appropriate.

At the same time the old algorithm will start its EOL and all references to that are renamed to indicate legacy. The old algorithm does not capture all aspects of the hashring and will not warn about programmer error in the hashring.

The newly added replica checksummer will walk the ring from the beginning to the end and capture all significant datapoints of a replicapoint in its checksum that should prevent two rings that are out of sync to provide the same checksum.

type Checksum interface {
// Compute calculates the checksum for the hashring that is passed in.
// Compute will be called while having atleast a readlock on the hashring so
// it is safe to read from the ring, but not safe to chagne the ring. There
Copy link
Contributor

Choose a reason for hiding this comment

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

s/chagne/change

ring.tree.root.walk(func(node *redBlackNode) bool {
buffer.WriteString(strconv.Itoa(node.key.(replicaPoint).point))
buffer.WriteString("-")
buffer.WriteString(node.value.(string))
Copy link
Contributor

@mennopruijssers mennopruijssers Nov 30, 2016

Choose a reason for hiding this comment

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

Doesn't it make more sense to use node.key.identity instead of node.value here?
ignore this

if r.checksum != old {
func (r *HashRing) Checksums() (checksums map[string]uint32) {
r.RLock()
// even though the map is immutable the pointer to it is not so it requires
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a check if checksums are already calculated and compute them if not?

r.logger.WithFields(bark.Fields{
"checksum": r.checksum,
"checksum": r.legacyChecksum,
"oldChecksum": old,
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to log the other checksums?

r.checksums[name] = checksummer.Compute(r)
}

// calculate the legacy identy only based checksum
Copy link
Contributor

Choose a reason for hiding this comment

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

s/identy/identity

// Compute will be called while having atleast a readlock on the hashring so
// it is safe to read from the ring, but not safe to chagne the ring. There
// might be multiple Checksum Computes initiated at the same time, but every
// Checksum will only be called once per hashring at once
Copy link
Contributor

@mennopruijssers mennopruijssers Nov 30, 2016

Choose a reason for hiding this comment

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

every Checksum will only be called once per hashring at once

not sure if we should define this behaviour. Why restrict us when not needed?


// addressChecksum calculates checksums for all addresses that are added to the
// hashring.
type addressChecksum struct{}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we use nor need the old style addressChecksum


// Checksum computes a checksum for an instance of a HashRing. The
// checksum can be used to compare two rings for equality.
type Checksum interface {
Copy link
Contributor

@CorgiMan CorgiMan Dec 12, 2016

Choose a reason for hiding this comment

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

I don't think we should have an interface here. A simple func Compute(ring *HashRing) function would be sufficient. Any reason we want this interface?

Also the interface name Checksumer with a Checksum method would be more idiomatic I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't agree here. A function can also implement an interface when needed, but if you want to use a struct it is harder if you don't use an interface as input.

The naming you are right on, we should call the interface Checksummer.

@mennopruijssers mennopruijssers changed the base branch from feature/identity-carry-over to dev December 19, 2016 12:20
@mennopruijssers mennopruijssers merged commit 3045cbf into dev Dec 19, 2016
@mennopruijssers mennopruijssers deleted the feature/ring-multi-checksum branch December 19, 2016 13:52
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.

None yet

3 participants