/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.coordinator.client.service;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
import org.slf4j.Logger;
import java.util.concurrent.TimeUnit;
/**
* This class holds a coordinator lock. Because this class implements AutoCloseable,
* it enables caller to use Java 7 syntax like:
* try (LockHolder lock = new LockHolder(...)) { ... }
*/
public class InterProcessLockHolder implements AutoCloseable {
InterProcessLock lock;
Logger log;
String name;
private InterProcessLockHolder() {
}
public static InterProcessLockHolder acquire(CoordinatorClient client, String lockName, Logger log, int timeoutMillis) throws Exception {
InterProcessLock lock = client.getLock(lockName);
if (!lock.acquire(timeoutMillis, TimeUnit.MILLISECONDS)) {
if (log != null) {
log.info("Failed to take lock {} in {} ms", lockName, timeoutMillis);
}
return null;
}
if (log != null) {
log.info("Acquired lock: {}", lockName);
}
InterProcessLockHolder holder = new InterProcessLockHolder();
holder.lock = lock;
holder.name = lockName;
holder.log = log;
return holder;
}
public InterProcessLockHolder(CoordinatorClient client, String lockName, Logger log) throws Exception {
this(client, lockName, log, false); // a lock for all DR sites as default
}
public InterProcessLockHolder(CoordinatorClient client, String lockName, Logger log, boolean siteLocalLock) throws Exception {
this.name = lockName;
this.log = log;
if (siteLocalLock) {
this.lock = client.getSiteLocalLock(lockName);
} else {
this.lock = client.getLock(lockName);
}
this.lock.acquire();
if (this.log != null) {
this.log.info("Acquired lock: {}", this.name);
}
}
public InterProcessLock getLock() {
return this.lock;
}
@Override
public void close() throws Exception {
if (this.lock != null) {
try {
this.lock.release();
} catch (Exception e) {
if (this.log != null) {
this.log.error(String.format("Failed to release lock: %s", this.name), e);
}
throw e;
}
if (this.log != null) {
this.log.info("Released lock {}", this.name);
}
this.lock = null;
}
}
}