Class BambooClusterLockServiceImpl

java.lang.Object
com.atlassian.beehive.db.DatabaseClusterLockService
com.atlassian.bamboo.beehive.BambooClusterLockServiceImpl
All Implemented Interfaces:
BambooClusterLockService, com.atlassian.beehive.ClusterLockService, com.atlassian.beehive.core.ManagedClusterLockService

public class BambooClusterLockServiceImpl extends com.atlassian.beehive.db.DatabaseClusterLockService implements BambooClusterLockService
Supports mutual exclusion operations in a cluster environment.
Since:
9.5
  • Field Details

  • Constructor Details

  • Method Details

    • releaseLocksHeldByNode

      public void releaseLocksHeldByNode()
      Description copied from interface: BambooClusterLockService
      Releases any locks held by the this node.
      Specified by:
      releaseLocksHeldByNode in interface BambooClusterLockService
    • tryAcquireLock

      public boolean tryAcquireLock(@NotNull @NotNull String lockName, long lockTimeoutSeconds)
      Description copied from interface: BambooClusterLockService
      Attempts to acquire ownership of a named lock by current cluster node. A lock should be treated as eligible to be acquired when one of the following is true:
      • It has no node set as an owner
      • It has the current node set as an owner
      • It has an other node set as an owner, but its last update time is older than the specified timeout
      Specified by:
      tryAcquireLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
      lockTimeoutSeconds - time (in seconds) after which the lock can be taken over
      Returns:
      true if we acquired the lock, false if the locks already has a valid owner.
    • releaseLock

      public void releaseLock(@NotNull @NotNull String lockName)
      Description copied from interface: BambooClusterLockService
      Release ownership of a named lock by current cluster node.
      Specified by:
      releaseLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
    • lockForWriting

      public void lockForWriting(@Nonnull String lockName, long lockTimeoutSeconds)
      Description copied from interface: BambooClusterLockService
      Locks for READING the lock identified by the given name. A WRITE lock should be treated as eligible to be acquired when one of the following is true:
      • It has no node set as an owner of correspondent WRITE lock
      • It has no node set as an owner of any correspondent READ locks
      • It has nodes set as owners of correspondent READ/WRITE locks, but their last update times are older than the specified time
      This method waits (Thread.sleep()) for the READ/WRITE locks to be released in case they are taken. For an implementation with immediate success/failure, take a look at BambooClusterLockService.tryAcquireWriteLock(String, long).

      Important: this is a NON-REENTRANT implementation, i.e., if the node tries to acquire a lock that it already owns, then it will not be granted. Rationale: reentrant implementation requires mechanism to track re-entrancies in order to prevent releasing the lock before all operations are completed. It can be considered in the future.

      There is no limit for the number of nodes that can acquire READ lock simultaneously, but only one can acquire the correspondent WRITE.

      Make sure that BambooClusterLockService.unlockForWriting(String) is called in a try...finally block.

      *

      Specified by:
      lockForWriting in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
      lockTimeoutSeconds - time (in seconds) after which an existing WRITE lock doesn't block the READ ones anymore
    • unlockForWriting

      public void unlockForWriting(@Nonnull String lockName)
      Description copied from interface: BambooClusterLockService
      Unlocks the WRITING part of the lock identified by the given name.
      Specified by:
      unlockForWriting in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
    • lockForReading

      public void lockForReading(@Nonnull String lockName, long lockTimeoutSeconds)
      Description copied from interface: BambooClusterLockService
      Locks for READING the lock identified by the given name. A READ lock should be treated as eligible to be acquired when one of the following is true:
      • It has no node set as an owner of correspondent WRITE lock
      • It has an node set as an owner of correspondent WRITE lock, but its last update time is older than the specified time
      This method waits (Thread.sleep()) for the WRITE lock to be released in case it is taken. For an implementation with immediate success/failure, take a look at BambooClusterLockService.tryAcquireReadLock(String, long).

      Important: this is a NON-REENTRANT implementation, i.e., if the node tries to acquire a lock that it already owns, then it will not be granted. Rationale: reentrant implementation requires mechanism to track re-entrancies in order to prevent releasing the lock before all operations are completed. It can be considered in the future.

      There is no limit for the number of nodes that can acquire READ lock simultaneously, but only one can acquire the correspondent WRITE (see BambooClusterLockService.lockForWriting(String, long).

      Make sure that BambooClusterLockService.unlockForReading(String) is called in a try...finally block.

      *

      Specified by:
      lockForReading in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
      lockTimeoutSeconds - time (in seconds) after which an existing WRITE lock doesn't block the READ ones anymore
    • lockForReading

      @VisibleForTesting public void lockForReading(@Nonnull String lockName, @NotNull @NotNull String nodeId, long lockTimeoutSeconds)
    • unlockForReading

      public void unlockForReading(@Nonnull String lockName)
      Description copied from interface: BambooClusterLockService
      Unlocks the READING part of the lock identified by the given name.
      Specified by:
      unlockForReading in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
    • unlockForReading

      @VisibleForTesting public void unlockForReading(@Nonnull String lockName, @NotNull @NotNull String nodeId)
    • tryAcquireReadLock

      public boolean tryAcquireReadLock(@NotNull @NotNull String lockName, long lockTimeoutSeconds)
      Description copied from interface: BambooClusterLockService
      Attempts to acquire READ ownership of a named lock by current cluster node. A READ lock should be treated as eligible to be acquired when one of the following is true:
      • It has no node set as an owner of correspondent WRITE lock
      • It has an node set as an owner of correspondent WRITE lock, but its last update time is older than the specified time
      Important: this is a NON-REENTRANT implementation, i.e., if the node tries to acquire a lock that it already owns, then it will not be granted. Rationale: reentrant implementation requires mechanism to track reentrancies in order to prevent releasing the lock before all operations are completed. It can be considered in the future.

      There is no limit for the number of nodes that can acquire READ lock simultaneously, but only one can acquire the correspondent WRITE (see BambooClusterLockService.tryAcquireWriteLock(String,long).

      Make sure that BambooClusterLockService.releaseReadLock(String) is called properly.

      There is no central entity managing a waiting list and granting permissions based on some criterion. Therefore, clients will be granted or denied immediately and it's up to them to try again.

      Specified by:
      tryAcquireReadLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
      lockTimeoutSeconds - time (in seconds) after which an existing WRITE lock doesn't block the READ ones
      Returns:
      true if we acquired the READ lock, false otherwise.
    • releaseReadLock

      public void releaseReadLock(@NotNull @NotNull String lockName)
      Description copied from interface: BambooClusterLockService
      Release READ ownership of a named lock by current cluster node.
      Specified by:
      releaseReadLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
    • tryAcquireWriteLock

      public boolean tryAcquireWriteLock(@NotNull @NotNull String lockName, long lockTimeoutSeconds)
      Description copied from interface: BambooClusterLockService
      AttemptS to acquire WRITE ownership of a named lock by current cluster node. A WRITE lock should be treated as eligible to be acquired when one of the following is true:
      • It has no node set as an owner of correspondent WRITE lock
      • It has no node set as an owner of correspondent READ locks
      • It has nodes set as owners of correspondent READ/WRITE locks, but their last update times are older than the specified time
      Important: this is a NON-REENTRANT implementation, i.e., if the node tries to acquire a lock that it already owns, then it will not be granted. Rationale: reentrant implementation requires mechanism to track reentrancies in order to prevent releasing the lock before all operations are completed. It can be considered in the future.

      There is no limit for the number of nodes that can acquire READ lock simultaneously, but only one can acquire the correspondent WRITE.

      Make sure that BambooClusterLockService.releaseReadLock(String) is called properly.

      There is no central entity managing a waiting list and granting permissions based on some criterion. Therefore, clients will be granted or denied immediately and it's up to them to try again.

      Specified by:
      tryAcquireWriteLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
      lockTimeoutSeconds - time (in seconds) after which the WRITE lock can be taken over
      Returns:
      true if we acquired the WRITE lock, false otherwise.
    • releaseWriteLock

      public void releaseWriteLock(@NotNull @NotNull String lockName)
      Description copied from interface: BambooClusterLockService
      Release READ ownership of a named lock by current cluster node.
      Specified by:
      releaseWriteLock in interface BambooClusterLockService
      Parameters:
      lockName - the globally unique id of the lock
    • shutdown

      @PreDestroy public void shutdown()
      Description copied from interface: BambooClusterLockService
      Shuts the service down, stopping all accessory jobs (e..g: lock renewer) for all locks.
      Specified by:
      shutdown in interface BambooClusterLockService
      Overrides:
      shutdown in class com.atlassian.beehive.db.DatabaseClusterLockService
    • getReadLockName

      @NotNull @VisibleForTesting public static @NotNull String getReadLockName(@NotNull @NotNull String lockName)
    • getReadLockNameForNode

      @NotNull @VisibleForTesting public static @NotNull String getReadLockNameForNode(@NotNull @NotNull String lockName, @NotNull @NotNull String nodeId)
    • getWriteLockName

      @NotNull @VisibleForTesting public static @NotNull String getWriteLockName(@NotNull @NotNull String lockName)