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

Early termination on session expiration to avoid unnecessary lock waiting #19597

Open
justlorain opened this issue Mar 13, 2025 · 0 comments · May be fixed by #19598
Open

Early termination on session expiration to avoid unnecessary lock waiting #19597

justlorain opened this issue Mar 13, 2025 · 0 comments · May be fixed by #19598

Comments

@justlorain
Copy link

What would you like to be added?

As mentioned in the concurrency/Mutex TODO,

// TODO: early termination if the session key is deleted before other session keys with smaller revisions.
the current implementation causes unnecessary waiting when a session expires. The following example illustrates this issue.

Suppose three clients (A, B, and C) sequentially call the Lock method

func (m *Mutex) Lock(ctx context.Context) error {
to acquire a lock. At this point, A holds the lock, B is waiting for A (waiting for A’s key to be deleted), and C is waiting for B. Both client B and client C are blocked in the waitDeletes method.
func waitDeletes(ctx context.Context, client *v3.Client, pfx string, maxCreateRev int64) error {
Now, if client C’s session cancels lease refresh using the Orphan method,
func (s *Session) Orphan() {
the key held by client C in the waiting queue will be automatically deleted when the lease expires. However, client C will still remain blocked in the waitDeletes method until B’s key is deleted. Only then will client C be able to detect, through the check
// make sure the session is not expired, and the owner key still exists.
gresp, werr := client.Get(ctx, m.myKey)
if werr != nil {
m.Unlock(client.Ctx())
return werr
}
if len(gresp.Kvs) == 0 { // is the session key lost?
return ErrSessionExpired
}
in the Lock method, that its key has already been deleted, thus returning the ErrSessionExpired error.

To resolve this issue, we can Watch for the deletion events of both the key with a smaller revision and the key held by the current client. This way, we can return immediately when the session expires instead of waiting until all keys with smaller revisions have been deleted.

Why is this needed?

Resolve the situation described in the TODO and reduce unnecessary lock waiting.

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

Successfully merging a pull request may close this issue.

1 participant