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

Allow update without resource version #10074

Merged
merged 1 commit into from Jun 24, 2015

Conversation

nikhiljindal
Copy link
Contributor

Updating code to populate the user given object with the resource version of the latest etcd object, if the user given object does not have a resource version.

// Pass an EtcdUpdateFunc to EtcdHelper.GuaranteedUpdate to make an etcd update that is guaranteed to succeed.
// See the comment for GuaranteedUpdate for more detail.
type EtcdUpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error)
type EtcdUpdateFunc func(input runtime.Object, node *etcd.Node) (output runtime.Object, ttl *uint64, err error)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replacing ResponseMeta with etcd.Node should be fine as per #8724 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

But we didn't want to do that for coupling reasons....

Copy link
Contributor

Choose a reason for hiding this comment

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

Dan convinced me it was a bad idea and I agreed

Copy link
Contributor

Choose a reason for hiding this comment

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

Conversation lost to the mists of github history, but basically: introduces coupling and encourages bad patterns - generic etcd should be generally isolated from exact etcd objects for test ability, and also callers should not be encouraged to accidentally (or intentionally) start using the node value directly

Copy link
Member

Choose a reason for hiding this comment

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

We could add ModifiedIndex to ResponseMeta, then (named ResourceVersion?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I can add node.Expiration and node.ModifiedIndex to ResponseMeta and then change e.Helper.Versioner.UpdateObject() to take modified index and expiration instead of the whole node, if this is a concern. Based on that discussion, I thought @smarterclayton had convinced @lavalamp that its fine to pass node, but looks like thats not the case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah the other way around. I fought but then conceded because he was right - pass what you need, not what you think you'll want. :)

----- Original Message -----

// Pass an EtcdUpdateFunc to EtcdHelper.GuaranteedUpdate to make an etcd
update that is guaranteed to succeed.
// See the comment for GuaranteedUpdate for more detail.
-type EtcdUpdateFunc func(input runtime.Object, res ResponseMeta) (output
runtime.Object, ttl *uint64, err error)
+type EtcdUpdateFunc func(input runtime.Object, node *etcd.Node) (output
runtime.Object, ttl *uint64, err error)

Yes. I can add node.Expiration and node.ModifiedIndex to ResponseMeta and
then change e.Helper.Versioner.UpdateObject() to take modified index and
expiration instead of the whole node, if this is a concern. Based on that
discussion, I thought @smarterclayton had convinced @lavalamp that its fine
to pass node, but looks like thats not the case.


Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/10074/files#r32851841

Copy link
Member

Choose a reason for hiding this comment

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

:) :)

Copy link
Member

Choose a reason for hiding this comment

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

Please keep response meta. You don't need to change this at all, the latest resource version is embedded in the object passed to the SimpleEtcdUpdateFunc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted that change, so that this still takes a ResponseMeta and not etcd.Node

@nikhiljindal
Copy link
Contributor Author

@@ -271,10 +272,21 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool
if err != nil {
return nil, false, err
}
// If the object specified by the user does not have a resource version,
Copy link
Contributor

Choose a reason for hiding this comment

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

I would want this feature to be optional on a type by type basis - opt in. We have a few objects where I'd want to discourage this pattern.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that we ever want to encourage this pattern, but it needs to exist, and I'd prefer that it be implemented in the server rather than via a RMW loop in the client. We could create an UpdateOption, but that would be more work, and then we'd need to generate a better error message for the case where resourceVersion == 0 but no forceUpdate option was specified, and we might still need to do something urgently to mitigate false conflicts with status updates.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I meant specifically in generic.Etcd as an implementor you have to enable this function. Prevents it being enabled by accident on new resources - I'd rather this be a deliberate decision.

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 can add a AllowUpdateWithoutResourceVersion() like AllowCreateOnUpdate() (https://github.com/GoogleCloudPlatform/kubernetes/blob/5520386b180d3ddc4fa7b7dfe6f52642cc0c25f3/pkg/api/rest/update.go#L35) in RESTUpdateStrategy?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, something like that. That allows us to add something to resttest that you indeed fail if that is false.

----- Original Message -----

@@ -271,10 +272,21 @@ func (e *Etcd) Update(ctx api.Context, obj
runtime.Object) (runtime.Object, bool
if err != nil {
return nil, false, err
}

  • // If the object specified by the user does not have a resource version,

I can add a AllowUpdateWithoutResourceVersion() like AllowCreateOnUpdate()
(https://github.com/GoogleCloudPlatform/kubernetes/blob/5520386b180d3ddc4fa7b7dfe6f52642cc0c25f3/pkg/api/rest/update.go#L35)
in RESTUpdateStrategy?


Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/10074/files#r32854948

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added an AllowUnconditionalUpdate() and using that here

@k8s-bot
Copy link

k8s-bot commented Jun 19, 2015

GCE e2e build/test passed for commit 13ca0cf73f20b926021e370132e84604deed81b6.

@bgrant0607 bgrant0607 self-assigned this Jun 19, 2015
@bgrant0607 bgrant0607 added this to the v1.0 milestone Jun 19, 2015
// If the object specified by the user does not have a resource version,
// then populete it with the latest version.
// Else, we check that the version specified by the user matches the version of latest etcd object.
useLatestResourceVersion := false
Copy link
Member

Choose a reason for hiding this comment

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

I would call this unsafeUpdate, unconditionalUpdate, forceUpdate, or something like that.

Copy link
Member

Choose a reason for hiding this comment

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

allowUnsafeUpdates?

Copy link
Member

Choose a reason for hiding this comment

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

er, reading more closely-- unconditionalUpdate or clobber might be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

renamed to allowUnconditionalUpdate

// If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version,
// then we populate it with the latest version.
// Else, we check that the version specified by the user matches the version of latest etcd object.
allowUnconditionalUpdate := false
Copy link
Member

Choose a reason for hiding this comment

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

Suggest:

doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate()

You're not just allowing it, you're doing it...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@lavalamp
Copy link
Member

Just a few nits, otherwise looks good.

@nikhiljindal nikhiljindal force-pushed the retryUpdate branch 2 times, most recently from e13bafd to ed56655 Compare June 20, 2015 01:28
@nikhiljindal
Copy link
Contributor Author

Updated code as per comments.
@lavalamp PTAL.

@k8s-bot
Copy link

k8s-bot commented Jun 20, 2015

GCE e2e build/test passed for commit ed56655e3a10992b63b4361ead24885c869c2352.

@lavalamp
Copy link
Member

LGTM

@lavalamp lavalamp added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 22, 2015
@nikhiljindal
Copy link
Contributor Author

Thanks! Added a test case for unconditional update to pkg/registry/generic/etcd/etcd_test.go.

@k8s-bot
Copy link

k8s-bot commented Jun 22, 2015

GCE e2e build/test passed for commit 5aeb1bc558aaacdb76513b2e81c1815308a6404f.

@j3ffml
Copy link
Contributor

j3ffml commented Jun 22, 2015

A test that was causing Shippable timeouts is disabled at head. Should be green after rebase.

@nikhiljindal
Copy link
Contributor Author

Rebased

@k8s-bot
Copy link

k8s-bot commented Jun 23, 2015

GCE e2e build/test passed for commit 221ae4d.

@nikhiljindal nikhiljindal reopened this Jun 23, 2015
@j3ffml j3ffml assigned bgrant0607 and unassigned lavalamp Jun 23, 2015
@j3ffml
Copy link
Contributor

j3ffml commented Jun 23, 2015

Per new merge policy, please add a brief risk assessment.

@nikhiljindal
Copy link
Contributor Author

Risk assessment: medium-low.
This change only affects the UPDATE operation on apiserver.

@nikhiljindal
Copy link
Contributor Author

@brendandburns or @davidopp for another LGTM.

// Update the object's resource version to match the latest etcd object's resource version.
err = e.Helper.Versioner.UpdateObject(obj, res.Expiration, res.ResourceVersion)
if err != nil {
return nil, nil, err
Copy link
Member

Choose a reason for hiding this comment

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

is there some reason why you don't return obj, nil, err here?

Copy link
Member

Choose a reason for hiding this comment

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

oh sorry, never mind, this is an error case.

@davidopp
Copy link
Member

LGTM

mbforbes added a commit that referenced this pull request Jun 24, 2015
Allow update without resource version
@mbforbes mbforbes merged commit 11f9fd1 into kubernetes:master Jun 24, 2015
@bgrant0607
Copy link
Member

Thanks. It looks like the API documentation already assumed we were doing this:
https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#concurrency-control-and-consistency

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm "Looks good to me", indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants