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

Changes for Successful for Anti-Entropy Replication #15

Merged
merged 5 commits into from
Jan 10, 2022

Conversation

bbengfort
Copy link
Contributor

@bbengfort bbengfort commented Dec 24, 2021

This PR implements several changes to ensure that Honu can be used effectively for anti-entropy replication including:

  • Adds an Update method (see below).
  • Adds zero version helpers and comparisons.
  • Refactors the Gossip RPC to be bilateral streaming instead of a unary RPC.

Update Method

Anti-Entropy requires the ability to put objects directly to the database without version information being modified. E.g. a repair means placing the version as it was from the remote locally. If the version information was modified during replication then the replication itself would cause updates that would keep bouncing back and forth.

Note that this means we're ending up with method pairs for user interactions and replica interactions: Get/Object, Put/Update - we'll probably also want Delete/Destroy. The user actions: Get, Put, and Delete modify version information while the replica actions Object, Update, and Destroy change the underlying state of the database not just the object.

Version helpers

The first version of an object is {"pid": P, "version": 1, "parent": null}; however replicas need to say they don't have an object, requiring a zero version, which can either be an empty or zero-valued struct or nil.

Bidirectional Streaming Gossip RPC

The original Gossip RPC in the Replication service was a unary RPC; however bilateral anti-entropy requires both a push and a pull. In the unary mechanism, not only is pagination required, but also a secondary request to do the pull (along with trickier state tracking). Refactoring to a bidirectional stream not only improves performance but also prevents the need for pagination and simplifies the anti-entropy implementation.

This PR blocks trisacrypto/directory#280

Anti-Entropy requires the ability to put objects directly to the
database without version information being modified - this PR adds that
method. We're ending up with method pairs: Get/Object, Put/Update -
we'll probably also want Delete/Destroy.
@codecov
Copy link

codecov bot commented Dec 24, 2021

Codecov Report

Merging #15 (514eb82) into main (7ab6fd1) will increase coverage by 0.24%.
The diff coverage is 60.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #15      +/-   ##
==========================================
+ Coverage   54.13%   54.37%   +0.24%     
==========================================
  Files           9        9              
  Lines         460      480      +20     
==========================================
+ Hits          249      261      +12     
- Misses        173      177       +4     
- Partials       38       42       +4     
Impacted Files Coverage Δ
honu.go 45.60% <55.55%> (+1.67%) ⬆️
object/object.go 47.61% <100.00%> (+5.51%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7ab6fd1...514eb82. Read the comment docs.

@bbengfort bbengfort changed the title Adds Update Method for Anti-Entropy Changes for Successful for Anti-Entropy Replication Jan 6, 2022
Copy link
Contributor

@pdeziel pdeziel left a comment

Choose a reason for hiding this comment

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

Looks good to me, I just had one question below.

@@ -26,6 +26,9 @@ func TestTombstone(t *testing.T) {

func TestVersionIsLater(t *testing.T) {
v1 := &Version{Pid: 8, Version: 42}
require.True(t, v1.IsLater(nil))
require.True(t, v1.IsLater(&VersionZero))
require.False(t, VersionZero.IsLater(v1))
Copy link
Contributor

Choose a reason for hiding this comment

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

Good checks. Is there any situation where we would end up comparing two VersionZeros? Do we want to have that test case here anyway to validate our logic?

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 suppose it's possible; I'll add the following:

require.False(t, VersionZero.IsLater(nil))
require.False(t, VersionZero.IsLater(VersionZero))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Turns out that this was a good catch VersionZero.IsLater(nil) was True - so I had to implement a minor change to fix that! Thanks for suggesting the test!

bbengfort and others added 2 commits January 10, 2022 15:33
Co-authored-by: Patrick Deziel <42919891+pdeziel@users.noreply.github.com>
@bbengfort bbengfort merged commit ce31ee3 into main Jan 10, 2022
@bbengfort bbengfort deleted the place-objects-anti-entropy branch January 10, 2022 21:42
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