All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.exhibitor.core.config.consul.ConsulKvLock Maven / Gradle / Ivy

package com.netflix.exhibitor.core.config.consul;

import com.google.common.base.Optional;
import com.orbitz.consul.Consul;
import com.orbitz.consul.KeyValueClient;
import com.orbitz.consul.model.kv.Value;
import com.orbitz.consul.model.session.ImmutableSession;
import com.orbitz.consul.option.QueryOptions;

import java.math.BigInteger;
import java.util.concurrent.TimeUnit;

public class ConsulKvLock {
    private final Consul consul;
    private final String path;
    private final String name;
    private final String ttl;
    private String sessionId;

    /**
     * @param consul consul client instance for connecting to consul cluster
     * @param path consul key-value path to lock
     * @param name a descriptive name for the lock
     * @param ttl TTL, in seconds, for the consul session underpinning the lock
     */
    public ConsulKvLock(Consul consul, String path, String name, Integer ttl) {
        this.consul = consul;
        this.path = path;
        this.name = name;
        this.ttl = ttl != null ? String.format("%ds", ttl) : null;
        this.sessionId = null;
    }

    /**
     * @param consul consul client instance for connecting to consul cluster
     * @param path consul key-value path to lock
     * @param name a descriptive name for the lock
     */
    public ConsulKvLock(Consul consul, String path, String name) {
        this(consul, path, name, 60);
    }

    private String createSession() {
        final ImmutableSession session = ImmutableSession.builder()
                .name(name)
                .ttl(Optional.fromNullable(ttl))
                .build();
        return consul.sessionClient().createSession(session).getId();
    }

    private void destroySession() {
        consul.sessionClient().destroySession(sessionId);
        sessionId = null;
    }

    public boolean acquireLock(long maxWait, TimeUnit unit) {
        KeyValueClient kv = consul.keyValueClient();
        sessionId = createSession();

        Optional value = kv.getValue(path);

        if (kv.acquireLock(path, sessionId)) {
            return true;
        }

        BigInteger index = BigInteger.valueOf(value.get().getModifyIndex());
        kv.getValue(path, QueryOptions.blockMinutes((int) unit.toMinutes(maxWait), index).build());

        if (!kv.acquireLock(path, sessionId)) {
            destroySession();
            return false;
        } else {
            return true;
        }
    }

    public void releaseLock() {
        try {
            KeyValueClient kv = consul.keyValueClient();
            Optional value = kv.getValue(path);

            if (value.isPresent()) {
                Optional session = value.get().getSession();
                if (session.isPresent()) {
                    kv.releaseLock(path, session.get());
                }
            }
        } finally {
            destroySession();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy