Tatha
Tatha

Reputation: 1293

Apache Curator Lock Recipes Revoking

I am trying to test the revocable Locking in Apache Curator. I have two threads which tries to acquire a lock. If the first test acquires the lock, the second thread can ask the first thread to release the lock so that the 2nd thread can acquire it

        RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMills, maxRetries);
        CuratorFramework client = CuratorFrameworkFactory.newClient(hosts, retryPolicy);
        client.start();

        final InterProcessMutex lock = new InterProcessMutex(client, lockBasePath);

        Collection<String> nodes =  lock.getParticipantNodes();

        lock.makeRevocable(new RevocationListener<InterProcessMutex>(){

            @Override
            public void revocationRequested(InterProcessMutex lock1) {
                try {
                    if(lock.isAcquiredInThisProcess()){
                        lock.release();
                    }

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        });

        if(nodes!=null && !nodes.isEmpty()){
            Revoker.attemptRevoke(client, nodes.iterator().next());
        }

        if (lock.acquire(waitTimeSeconds, TimeUnit.SECONDS)) {
            try {
                doSomeWork(lockName);
            } finally {
                lock.release();
            }
        } else {
            System.err.printf("%s timed out after %d seconds waiting to acquire lock on %s\n",
                    lockName, waitTimeSeconds, lockPath);
        }

The problem is, when the 2nd thread calls the attemptRevoke, the callback async method is called on the first process, but since its a call back method that's a third thread, and if that invokes the lock.release it throws an Exception

java.lang.IllegalMonitorStateException: You do not own the lock

That is as per the api

release() Perform one release of the mutex if the calling thread is the same thread that acquired it.

So basically this is never possible because callbacks will always be another thread. Is there any other way to achieve this?

Thanks for any suggestions

-Tatha

Upvotes: 2

Views: 2085

Answers (2)

Wuaner
Wuaner

Reputation: 969

You can use InterProcessSemaphoreMutex instead of InterProcessMutex to release the lock in another thread.

ref: Ability to release an InterProcessMutex from another thread #117

Upvotes: 3

Randgalt
Randgalt

Reputation: 2956

Your RevocationListener should interrupt the thread that holds the lock. Then, that thread can release the lock.

Upvotes: 1

Related Questions