unlockKey tries to unlock the lock by verifying the lock with token.
(ctx context.Context, key string, token []byte)
| 37 | |
| 38 | // unlockKey tries to unlock the lock by verifying the lock with token. |
| 39 | func (dm *DMap) unlockKey(ctx context.Context, key string, token []byte) error { |
| 40 | lkey := dm.name + key |
| 41 | // Only one unlockKey should work for a given key. |
| 42 | dm.s.locker.Lock(lkey) |
| 43 | defer func() { |
| 44 | err := dm.s.locker.Unlock(lkey) |
| 45 | if err != nil { |
| 46 | dm.s.log.V(3).Printf("[ERROR] Failed to release the fine grained lock for key: %s on DMap: %s: %v", key, dm.name, err) |
| 47 | } |
| 48 | }() |
| 49 | |
| 50 | // get the key to check its value |
| 51 | entry, err := dm.Get(ctx, key) |
| 52 | if errors.Is(err, ErrKeyNotFound) { |
| 53 | return ErrNoSuchLock |
| 54 | } |
| 55 | if err != nil { |
| 56 | return err |
| 57 | } |
| 58 | |
| 59 | // the lock is released by the node(timeout) or the user |
| 60 | if !bytes.Equal(entry.Value(), token) { |
| 61 | return ErrNoSuchLock |
| 62 | } |
| 63 | |
| 64 | // release it. |
| 65 | _, err = dm.deleteKeys(ctx, key) |
| 66 | if err != nil { |
| 67 | return fmt.Errorf("unlock failed because of delete: %w", err) |
| 68 | } |
| 69 | return nil |
| 70 | } |
| 71 | |
| 72 | // Unlock takes key and token and tries to unlock the key. |
| 73 | // It redirects the request to the partition owner, if required. |