-
Notifications
You must be signed in to change notification settings - Fork 78
=cluster efficient Membership Gossip serialization (proto + smart UniqueNode repetition avoidance) #676
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
Conversation
| ActorAddress actorAddress = 1; | ||
| UniqueNode uniqueNode = 2; | ||
| uint32 uniqueNodeIdentifier = 3; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is new, we allow carrying just the node id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
number ok? don't need to be string?
is this the same as ClusterMembershipSeenTableRow.uniqueNodeID? maybe use either *ID or *Identifier in all the names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good point, I couldn't decide what to go with, I guess ID
| // During deserialization the fields can be resolved against the membership to obtain full UniqueNode values if necessary. | ||
| uint32 ownerUniqueNodeID = 2; | ||
| ClusterMembershipSeenTable seenTable = 3; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments explain what we do here
|
|
||
| public var node: Node | ||
| public let nid: NodeID | ||
| public let nid: UniqueNodeID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that rename dawned on me during this work, much more correct i guess
|
|
||
| /// Serialize using uniqueNodeIdentifier specifically (or crash); | ||
| /// Used in situations where an enclosing message already has the unique nodes serialized and we can save space by avoiding to serialize them again. | ||
| public func toCompactReplicaNodeIDProto(context: Serialization.Context) throws -> ProtoVersionVector { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a bit manual but good enough for now... we could generalize this
TODO: make a ticket for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ticket #677
| public func member(byUniqueNodeID nid: UniqueNode.ID) -> Cluster.Member? { | ||
| // TODO: make this O(1) by allowing wrapper type to equality check only on NodeID | ||
| self._members.first(where: { $0.key.nid == nid })?.value | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: make a ticket
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#678 Make Membership.member(byUniqueNodeID) O(1)
| /// Base class to handle the repetitive setUp/tearDown code involved in most ActorSystem requiring tests. | ||
| // TODO: Document and API guarantees | ||
| open class ActorSystemTestBase: ClusteredNodesTestBase { | ||
| open class ActorSystemXCTestCase: ClusteredActorSystemsXCTestCase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should have split this out into other changeset... can do tomorrow
| let back = try system.serialization.deserialize(as: Cluster.Gossip.self, from: serialized) | ||
| "\(pretty: back)".shouldStartWith(prefix: "\(pretty: gossip)") // nicer human readable error | ||
| back.shouldEqual(gossip) // the actual sanity check | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the test showcasing the new thing. The "naive" impl ends up at 8000+ bytes here, and that's pretty bad; our new impl scales much better with cluster size as well.
yim-lee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of non-blocking suggestions/questions
| ActorAddress actorAddress = 1; | ||
| UniqueNode uniqueNode = 2; | ||
| uint32 uniqueNodeIdentifier = 3; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
number ok? don't need to be string?
is this the same as ClusterMembershipSeenTableRow.uniqueNodeID? maybe use either *ID or *Identifier in all the names?
| } | ||
|
|
||
| public struct NodeID: Hashable { | ||
| // TODO: move as UniqueNode.Identifier? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
| case .uniqueNodeID(let nid): | ||
| replicaVersion.replicaID.uniqueNodeIdentifier = nid.value | ||
| case .actorAddress: | ||
| throw SerializationError.unableToSerialize(hint: "Can't serialize using unique node identifier as replica id! Was: \(replicaID)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the error message correct?
| throw SerializationError.unableToSerialize(hint: "Can't serialize using unique node identifier as replica id! Was: \(replicaID)") | |
| throw SerializationError.unableToSerialize(hint: "Can't serialize using actor address as replica id! Was: \(replicaID)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
| return data.stringDebugDescription() | ||
| case .nioByteBuffer(let bufffer): | ||
| return bufffer.stringDebugDescription() | ||
| case .nioByteBuffer(let buffer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
|
Could not answer in line for some reason:
Yes, that's integer, the same as the ClusterMembershipSeenTableRow.uniqueNodeID now using uniqueNodeID everywhere |
|
Ci failure is a bit mysterious: #680 FAILED: weird build timeouts |
Motivation:
The membership gossip is sent around "constantly", it should be as small as possible.
It should scale O(n) and NOT worse (like it did today) with number of nodes.
Modifications:
Result: