func TryExclusiveKeyLock(lockDir string, key string) (*KeyLock, error) {
	return createAndLock(lockDir, key, keyLockExclusive|keyLockNonBlocking)
}
TryExclusiveLock takes an exclusive lock on the key without blocking.
lockDir is the directory where the lock file will be created.
It will return ErrLocked if any lock is already held.
package lock
import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"syscall"
	"github.com/hashicorp/errwrap"
)
const (
	defaultDirPerm     os.FileMode = 0660
	defaultFilePerm    os.FileMode = 0660
	defaultLockRetries             = 3
)
type keyLockMode uint
const (
	keyLockExclusive keyLockMode = 1 << iota
	keyLockShared
	keyLockNonBlocking
)
type KeyLock struct {
	lockDir string
	key     string
	keyLock *FileLock
}
func NewKeyLock(lockDir string, key string) (*KeyLock, error) {
	err := os.MkdirAll(lockDir, defaultDirPerm)
	if err != nil {
		return nil, err
	}
	keyLockFile := filepath.Join(lockDir, key)
	f, err := os.OpenFile(keyLockFile, os.O_RDONLY|os.O_CREATE, defaultFilePerm)
	if err != nil {
		return nil, errwrap.Wrap(errors.New("error creating key lock file"), err)
	}
	f.Close()
	keyLock, err := NewLock(keyLockFile, RegFile)
	if err != nil {
		return nil, errwrap.Wrap(errors.New("error opening key lock file"), err)
	}
	return &KeyLock{lockDir: lockDir, key: key, keyLock: keyLock}, nil
}
func (l *KeyLock) Close() {
	l.keyLock.Close()
}
func (l *KeyLock) TryExclusiveKeyLock() error {
	return l.lock(keyLockExclusive|keyLockNonBlocking, defaultLockRetries)
}