Skip to content

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

Open
@justlorain

Description

@justlorain

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions