-
Notifications
You must be signed in to change notification settings - Fork 9.9k
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
Add support for lease api to linearizability tests #15080
Conversation
Signed-off-by: Geeta Gharpure <geetagh@amazon.com>
Updated with review feedback from #15057. /cc @ahrtr @serathius |
Codecov Report
@@ Coverage Diff @@
## main #15080 +/- ##
==========================================
- Coverage 74.78% 74.60% -0.18%
==========================================
Files 415 415
Lines 34288 34288
==========================================
- Hits 25642 25582 -60
- Misses 7018 7062 +44
- Partials 1628 1644 +16
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
leaseId := lm.LeaseId(cid) | ||
if leaseId != 0 { | ||
err = c.LeaseRevoke(putCtx, leaseId) | ||
//if LeaseRevoke has failed, do not remove the mapping. | ||
if err == nil { | ||
lm.RemoveLeaseId(cid) | ||
} | ||
} |
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 you execute c.LeaseGrant
as well if there is no a leaseId related to the clientId in this case (LeaseRevoke
), just in the same way as you process PutWithLease
? Otherwise the (readWriteSingleKey) Write
will do nothing in this case.
The Delete operation might delete nothing if it happens before the related PUT
operation. But there is always a communication with the etcdserver.
I agree that the existing implementation is simpler.
Anyway, I am OK to discuss this in a separate PR.
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.
Overall looks good to me.
Thank you @geetasg
@@ -197,6 +224,24 @@ func initState(request EtcdRequest, response EtcdResponse) EtcdState { | |||
case Put: | |||
state.KeyValues[op.Key] = op.Value | |||
case Delete: | |||
case PutWithLease: | |||
if _, ok := state.Leases[op.LeaseID]; ok { |
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 should never happen as state.Leases
should be empty.
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.
updated in #15093
panic("old lease id found at init") | ||
} | ||
//attach to new lease id | ||
state.KeyLeases[op.Key] = op.LeaseID |
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.
How about calling attachToNewLease
here ?
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 the code in init - now putwithlease at init is nop since the lease wont be there. updated in #15093
if _, ok := state.Leases[op.LeaseID]; ok { | ||
state.KeyValues[op.Key] = op.Value | ||
//detach from old lease id but we dont expect that at init | ||
if _, ok := state.KeyLeases[op.Key]; ok { |
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.
Just skip 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.
updated in #15093
return s, EtcdResponse{Result: opResp, Revision: s.Revision} | ||
} | ||
|
||
func detachFromOldLease(s EtcdState, op EtcdOperation) EtcdState { |
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.
func detachFromOldLease(s EtcdState, op EtcdOperation) EtcdState { | |
func detachFromOldLease(s EtcdState, key string) EtcdState { |
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.
updated in #15093
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.
Looks good to me, but I think @serathius opinion is crucial here.
opResp[i].Deleted = 1 | ||
} | ||
case PutWithLease: | ||
if _, ok := s.Leases[op.LeaseID]; ok { |
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.
Question, does etcd allows to make a Put with lease that doesn't exist? I expect that it returns an client error, but maybe I remember wrong.
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.
Adding test result for quick ref -
Put with non existent lease -
{"level":"warn","ts":"2023-01-12T15:39:35.877-0800","caller":"txn/util.go:47","msg":"failed to apply request","took":"18.335µs","request":"header:<ID:7587867905305039876 > put:<key:"x" value_size:1 lease:4 >","response":"","error":"lease not found"}
client (etcdctl in my case) -
macbook % ./etcdctl put x y --lease=4
{"level":"warn","ts":"2023-01-12T15:39:35.878-0800","logger":"etcd-client","caller":"v3@v3.6.0-alpha.0/retry_interceptor.go:65","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00017e000/127.0.0.1:2379","method":"/etcdserverpb.KV/Put","attempt":0,"error":"rpc error: code = NotFound desc = etcdserver: requested lease not found"}
Error: etcdserver: requested lease not found
return s | ||
} | ||
|
||
func attachToNewLease(s EtcdState, op EtcdOperation) EtcdState { |
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.
func attachToNewLease(s EtcdState, op EtcdOperation) EtcdState { | |
func attachKeyToLease(s EtcdState, leaseID int64, key string) EtcdState { |
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.
updated in #15093
}, | ||
}, | ||
{ | ||
name: "Deleting a leased key - revoke should not increment revision", |
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.
One additional scenario would be useful, "Overriding a leased key should remove lease"
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.
there is a scenario for Put following PutWithLease. https://github.com/etcd-io/etcd/blob/main/tests/linearizability/model_test.go#L435. Do you mean something else? Can you please clarify what you mean by override? thanks
"sync" | ||
) | ||
|
||
type clientId2LeaseIdMapper interface { |
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.
What's the reason to map leases to clients? Would it be more interesting if we allowed every client to touch every lease? Changes needed:
- We just store available lease ids. Possibly with some limit to avoid explosion on to many LeaseGrant.
- When client needs to use lease it will take it out from storage to avoid racing with other clients. When client is done with a lease it can return it to storage, assuming it didn't revoke it.
Looks very good, my comments are mostly nits to make code simpler. I'm impressed. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Thanks much for the review @serathius @ahrtr and @ptabor . I will create a new PR to address the review comments in this one. |
Signed-off-by: Geeta Gharpure geetagh@amazon.com
Please read https://github.com/etcd-io/etcd/blob/main/CONTRIBUTING.md#contribution-flow.