(Quick Reference)

2 Usage - Reference Documentation

Authors: Bud Byrd

Version: 3.0.0

2 Usage

Mutexes are identified by an identifier. The identifier is an arbitrary string and should be well-known between the various parts of the application that utilize a particular mutex.

The distributedMutexHelper bean is the service that implements the interaction with distributed mutexes and can be injected into other managed Spring beans in your application.

This document does not detail the exact method signatures of the methods included in the distributedMutexHelper. The API documentation can be used for exact details of how to use any of the methods discussed here.

2.1 Acquiring A Mutex

The distributedMutexHelper.acquireMutex methods can be used to acquire a mutex lock for a given identifier. These methods return a string key, which is required to unlock the mutex.

If no mutex timeout is provided, the mutex will remain locked indefinitely until it is released. Otherwise, if a mutex timeout is provided, the mutex will remain valid until it is either released or it expires, at which time it can be locked by another process attempting to lock the mutex.

When attempting to acquire a locked mutex, an optional poll timeout can be provided. By default, this poll timeout is 0, which caused the method to only attempt to lock the mutex once. If a poll timeout is provided, the method will poll the mutex for as long as the poll timeout allows the mutex to be acquired. The interval of this polling is configurable as well.

2.2 Checking If A Mutex Is Locked

To check whether a mutex is locked, the distributedMutexHelper.isMutexLocked method can be used. The method returns true if the mutex has been locked by another process.

2.3 Releasing A Mutex

A mutex can be unlocked with the distributedMutexHelper.releaseMutexLock method, which requires both the mutex identifier and the lock key acquired when the mutex was locked. If the mutex's key matches the one provided to the releaseMutexLock call,it will be marked is unlocked.

If the key provided to the distributedMutexHelper.releaseMutexLock call does not match the one on the mutex, a warning will be logged and the mutex will not be unlocked.

It is important that processes that acquire a mutex have error handling logic in place so that the mutex is released even in the case of unrecoverable failure. If this is not done, a resource may be locked indefinitely, depending on the options used when the mutex was acquired.

2.4 Force A Mutex To Be Released

If a mutex was locked but never released, it may be necessary to force the release of the mutex lock regardless of the lock key. This should only be used as a means to restore the functionality of an application experiencing mutex dead locks, and never as part of normal mutex acquisition and releasing logic.

A mutex lock be can forcibly released using the distributedMutexHelper.forciblyReleaseMutex method. Only the mutex identifier is required for this operation.

If the use of this method is required, it may be a good idea to investigate why a mutex was locked and not released. Good error handling should cover the majority of the cases where a mutex becomes indefinitely locked.

2.5 A Quick Example

To illustrate how the plugin should be used, this is a trivial example of how to interact with a distributed mutex. The logic inside the mutex lock is not complex enough to warrant the use of a distributed mutex, but the intention is to demonstrate the interaction with the distributedMutexHelper.

package com.budjb.example

import com.budjb.mutex.DistributedMutexHelper

class MutexExampleService { /** * The distributed mutex helper bean. */ DistributedMutexHelper distributedMutexHelper

/** * Storing state in a singleton service is a bad idea unless you can isolate access to it. */ private int counter = 0

/** * The identifier for the mutex. */ static final String MUTEX_IDENTIFIER = 'example-counter-mutex'

/** * Every time the counter is accessed, it should be incremented. * * @return the current counter value */ int getCounter() throws LockNotAcquiredException { // Acquire the mutex lock. The key is used to unlock it later. // If the mutex can not be acquired, a LockNotAcquiredException will be thrown // by the distributedMutexHelper. Ideally your application will handle this // error. // // We will acquire the mutex for a period of 10 seconds. String key = distributedMutexHelper.acquireMutex(MUTEX_IDENTIFIER, 10000)

// Wrap our operation with a try/finally so that if any exception or error occurs, // the mutex will be released. While the mutex will time out in 10 seconds anyway, // this is especially important when a mutex has an indefinite lifespan (no timeout). // Your application can obviously handle different exception cases here as well, // but this example will not account for any exceptions thrown because of the simple // logic this method performs. try { return ++counter } finally { distributedMutexHelper.releaseMutexLock(MUTEX_IDENTIFIER, key) } } }