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

Add support for lease api to linearizability tests #15080

Merged
merged 1 commit into from
Jan 11, 2023

Conversation

geetasg
Copy link

@geetasg geetasg commented Jan 11, 2023

Signed-off-by: Geeta Gharpure <geetagh@amazon.com>
@geetasg
Copy link
Author

geetasg commented Jan 11, 2023

Updated with review feedback from #15057. /cc @ahrtr @serathius

@codecov-commenter
Copy link

Codecov Report

Merging #15080 (5b84526) into main (a992fb5) will decrease coverage by 0.17%.
The diff coverage is n/a.

@@            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     
Flag Coverage Δ
all 74.60% <ø> (-0.18%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
client/pkg/v3/fileutil/purge.go 68.85% <0.00%> (-6.56%) ⬇️
server/storage/mvcc/kvstore_compaction.go 95.65% <0.00%> (-4.35%) ⬇️
client/v3/concurrency/session.go 85.10% <0.00%> (-4.26%) ⬇️
server/proxy/grpcproxy/watch.go 92.48% <0.00%> (-4.05%) ⬇️
client/v3/leasing/cache.go 87.77% <0.00%> (-3.89%) ⬇️
server/etcdserver/api/rafthttp/msgappv2_codec.go 67.82% <0.00%> (-3.48%) ⬇️
server/etcdserver/api/rafthttp/pipeline.go 97.40% <0.00%> (-2.60%) ⬇️
client/v3/concurrency/election.go 79.68% <0.00%> (-2.35%) ⬇️
server/etcdserver/api/v3rpc/auth.go 79.34% <0.00%> (-2.18%) ⬇️
server/etcdserver/api/rafthttp/peer.go 85.06% <0.00%> (-1.95%) ⬇️
... and 16 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Comment on lines +102 to +109
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)
}
}
Copy link
Member

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.

Copy link
Member

@ahrtr ahrtr left a 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 {
Copy link
Member

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.

Copy link
Author

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
Copy link
Contributor

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 ?

Copy link
Author

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 {
Copy link
Member

Choose a reason for hiding this comment

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

Just skip it

Copy link
Author

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 {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func detachFromOldLease(s EtcdState, op EtcdOperation) EtcdState {
func detachFromOldLease(s EtcdState, key string) EtcdState {

Copy link
Author

Choose a reason for hiding this comment

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

updated in #15093

Copy link
Contributor

@ptabor ptabor 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, but I think @serathius opinion is crucial here.

opResp[i].Deleted = 1
}
case PutWithLease:
if _, ok := s.Leases[op.LeaseID]; ok {
Copy link
Member

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.

Copy link
Author

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 {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func attachToNewLease(s EtcdState, op EtcdOperation) EtcdState {
func attachKeyToLease(s EtcdState, leaseID int64, key string) EtcdState {

Copy link
Author

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",
Copy link
Member

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"

Copy link
Author

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 {
Copy link
Member

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.

@serathius
Copy link
Member

Looks very good, my comments are mostly nits to make code simpler. I'm impressed.

@serathius
Copy link
Member

Let's merge it to avoid conflicts with #15078
@geetasg can you address the comments in future PR?

@serathius serathius merged commit 3306639 into etcd-io:main Jan 11, 2023
@rchoulak

This comment was marked as off-topic.

@rchoulak

This comment was marked as off-topic.

@geetasg
Copy link
Author

geetasg commented Jan 11, 2023

Thanks much for the review @serathius @ahrtr and @ptabor . I will create a new PR to address the review comments in this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants