-
Notifications
You must be signed in to change notification settings - Fork 5
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
Introduce ExtendedObjectMetadata, holding Writes #87
Conversation
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.
I have to pause the review and I'm not done yet, but there's already some stuff.
newSubnet := obj.(*network.Subnet) | ||
newSubnet.ExtendedObjectMeta = oldSubnet.ExtendedObjectMeta | ||
now := network.Now() | ||
if newSubnet.Spec != oldSubnet.Spec { |
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 check is unneeded.
Currently spec is immutable for subnets (see *subnetStragey::ValidateUpdate
), and *subnetStragey::PrepareForUpdate
executes only for real updates, not for deletes followed by re-creates.
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.
Oh, right.
newNA := obj.(*network.NetworkAttachment) | ||
newNA.ExtendedObjectMeta = oldNA.ExtendedObjectMeta | ||
now := network.Now() | ||
if oldNA.Spec.Node != newNA.Spec.Node || oldNA.Spec.Subnet != newNA.Spec.Subnet || !SliceOfStringEqual(oldNA.Spec.PostCreateExec, newNA.Spec.PostCreateExec) || !SliceOfStringEqual(oldNA.Spec.PostDeleteExec, newNA.Spec.PostDeleteExec) { |
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.
All the checks on the spec fields but the one on postDeleteExec
are unneeded.
Currently all spec fields but postDeleteExec
are immutable for NetworkAttachments (see networkAttachmentStrategy::ValidateUpdate
), and networkAttachmentStrategy::PrepareForUpdate
executes only for real updates, not for deletes followed by re-creates.
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.
Actually, the CA "samples" the postDeleteExec
of an attachment when it creates a network interface for the attachment, and always ignores postDeleteExec
thereafter. We could therefore drop the check on NetworkAttachment's spec altogether.
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, less to check is better.
I do not see why the cited behavior means the PostDelectExec field does not need to be examined for changes.
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.
I do not see why the cited behavior means the PostDelectExec field does not need to be examined for changes.
You mean examined for changes in networkAttachmentStragey::PrepareForUpdate
?
Actually, you're right.
|
||
// GetWrite returns the write to the given section, or zero if there | ||
// was none. | ||
func (writes WriteSet) GetWrite(section string) ObjectWrite { |
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.
It's a nit, but how about this function returns a got
bool field as well, which is set to false when no write is found? The same change would also happen in the internal API version types file.
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 idea
|
||
// UnionLeft produces the union of the receiver and the other writes | ||
// that do not overlap with the receiver | ||
func (writes WriteSet) UnionLeft(others WriteSet) WriteSet { |
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 method and the other Union methods are never used (same observation for internal API version types). Do you plan other commits where they are used?
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.
Yes. I have some vague plans that use various of these.
func (writes WriteSet) UnionMin(others WriteSet) WriteSet { | ||
ans := others.Diff(writes) | ||
for _, wr := range writes { | ||
owr := others.GetWrite(wr.Section) |
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.
If others
does not contain a write for the given section, GetWrite
returns an empty ObjectWrite
, which will be added to ans
with an empty Section
field. How about adding owr.Section = wr.Section
?
Same applies to WriteSet::UnionMax
and the equivalent functions in the internal API types file.
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.
Yes, this logic is wrong for Min. For Max, it is guaranteed that the other will not be taken if it is the zero 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.
For Max, it is guaranteed that the other will not be taken if it is the zero value
Mmm... how is that guaranteed? AFAIU both UnionMin
and UnionMax
set ServerTime
even if owr
is the zero value, but Section
could be left unset.
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 expectation is that real server times are positive, so will win over zero in Max.
But I am rewriting both to use the extra bool.
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 expectation is that real server times are positive, so will win over zero in Max.
But this affects in no way handling of Section
.
} | ||
} | ||
|
||
func SliceOfStringEqual(x, y []string) bool { |
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 function is duplicated with the one in subnet strategy. Also, it is the negation of differ, one of the two could be therefore removed (I vote for differ
). We should place this function in the util package (not necessarily now, even in the future).
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.
Removed differ
. We can think about the right place to put a utitlity like SliceOfStringEqual
. In k/k, there is a lot of careful factoring of sources.
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.
Right, let's do that on another occasion though. I would also expect k/k to already have a function like this in some util pkg.
newNA := obj.(*network.NetworkAttachment) | ||
newNA.ExtendedObjectMeta = oldNA.ExtendedObjectMeta | ||
now := network.Now() | ||
if oldNA.Spec.Node != newNA.Spec.Node || oldNA.Spec.Subnet != newNA.Spec.Subnet || !SliceOfStringEqual(oldNA.Spec.PostCreateExec, newNA.Spec.PostCreateExec) || !SliceOfStringEqual(oldNA.Spec.PostDeleteExec, newNA.Spec.PostDeleteExec) { |
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.
Actually, the CA "samples" the postDeleteExec
of an attachment when it creates a network interface for the attachment, and always ignores postDeleteExec
thereafter. We could therefore drop the check on NetworkAttachment's spec altogether.
@@ -1057,7 +1070,7 @@ func (ca *ConnectionAgent) updateLocalAttachmentStatus(att *netv1a1.NetworkAttac | |||
updatedAtt.Status.PostCreateExecReport) | |||
|
|||
if att.Status.HostIP == "" { | |||
ca.attachmentCreateToStatusHistogram.Observe(tAfterUpdate.Truncate(time.Second).Sub(att.CreationTimestamp.Time).Seconds()) | |||
ca.attachmentCreateToStatusHistogram.Observe(updatedAtt.Writes.GetServerWriteTime(netv1a1.NASectionAddr).Sub(att.Writes.GetServerWriteTime(netv1a1.NASectionSpec)).Seconds()) |
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.
Shouldn't s/netv1a1.NASectionAddr/netv1a1.NASectionImpl/
?
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.
right
Introduced an additional metadata section to Subnet and NetworkEndpoint, holding a server-side timestamped record of the latest write to each section of the object. The timestamps are full precision, NOT truncated to a whole number of seconds. Updated ipam and connection agent to use those write stamps instead of the truncated creation timestamp in the relevant histograms. Also introduced a histogram of latency from (a) setting of status by local connection agent to (b) creation of remote ifc by remote connection agent.
3a6cb2a
to
3edb973
Compare
The force-push to 3edb973 is a rebase onto |
@@ -83,7 +84,7 @@ func (writes WriteSet) SetWrite(section string, serverTime Timestamp) WriteSet { | |||
func (writes WriteSet) Diff(others WriteSet) WriteSet { | |||
ans := make(WriteSet, 0, len(writes)) | |||
for _, wr := range writes { | |||
owr := others.GetWrite(wr.Section) | |||
owr, _ := others.GetWrite(wr.Section) |
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.
Other nit, but the following check could use the bool variable.
BTW, I am starting to get the idea that server-side apply is intended to have comprehensive coverage regardless of operation. That is being worked in |
There is also this: kubernetes/community#4218 (comment) |
Overlooked fixup
df4b789
to
fb1d177
Compare
Introduced an additional metadata section to Subnet and
NetworkEndpoint, holding a server-side timestamped record of the
latest write to each section of the object. The timestamps are full
precision, NOT truncated to a whole number of seconds.
Updated ipam and connection agent to use those write stamps instead of
the truncated creation timestamp in the relevant histograms. Also
introduced a histogram of latency from (a) setting of status by local
connection agent to (b) creation of remote ifc by remote connection
agent.
This may be viewed as a preview of the "managed fields" metadata that is coming along with server-side apply, to become pervasive in Kubernetes release 1.18. We are not ready to advance to release 1.18 yet; when we do, we may replace this with a use of the managed fields metadata.