package io.lumify.core.model.lock; import com.google.inject.Inject; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.locks.InterProcessLock; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import io.lumify.core.config.Configuration; import io.lumify.core.util.LumifyLogger; import io.lumify.core.util.LumifyLoggerFactory; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; public class LockRepository { private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(LockRepository.class); public static final String DEFAULT_PATH_PREFIX = "/lumify/locks"; private final CuratorFramework curatorFramework; private final String pathPrefix; private final Map<String, Object> localLocks = new HashMap<String, Object>(); @Inject public LockRepository(final CuratorFramework curatorFramework, final Configuration configuration) { this.curatorFramework = curatorFramework; this.pathPrefix = configuration.get(Configuration.LOCK_REPOSITORY_PATH_PREFIX, DEFAULT_PATH_PREFIX); } public Lock createLock(String lockName) { InterProcessLock l = new InterProcessMutex(this.curatorFramework, getPath(lockName)); return new Lock(l, lockName); } private String getPath(String lockName) { return this.pathPrefix + "/" + lockName; } public void lock(String lockName, final Runnable runnable) { lock(lockName, new Callable<Object>() { @Override public Object call() throws Exception { runnable.run(); return null; } }); } public <T> T lock(String lockName, Callable<T> callable) { LOGGER.debug("starting lock: %s", lockName); try { Object localLock = getLocalLock(lockName); synchronized (localLock) { Lock lock = createLock(lockName); return lock.run(callable); } } finally { LOGGER.debug("ending lock: %s", lockName); } } private Object getLocalLock(String lockName) { synchronized (localLocks) { Object localLock = localLocks.get(lockName); if (localLock == null) { localLock = new Object(); localLocks.put(lockName, localLock); } return localLock; } } }