No description, website, or topics provided.
Scala
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
project
src
.gitignore
.travis.yml
LICENSE
README.md
build.sbt

README.md

mongo-lock

Build Status Download

#Mongo-Lock

This is a utility that prevents multiple instances of the same application to perform an operation at the same time. This can be useful of example when a REST api has to be called at a scheduled time. Without this utility every instance of the application would call the REST api.

There are 2 variants that can be used to instigate a lock, LockKeeper for locking for a particular task and ExclusiveTimePeriodLock to lock exclusively for a given time period (i.e. stop other instances executing the task until I stop renewing the lock)

The utility uses mongodb to create a lock

##Usage

  1. Get access to mongodb
    val connection = {

          import play.api.Play.current
          ReactiveMongoPlugin.mongoConnector.db
   }
   val repo = LockMongoRepository(connection)
  1. Create a LockKeeper or ExclusiveTimePeriodLock.

For LockKeeper the forceLockRelease timeout allows other apps to release and get the lock if it was stuck for some reasons

    val lockKeeper = new LockKeeper {
    
        override def repo: LockRepository = repo //The repo created before
    
        override def lockId: String = "<something unique for the operation>"
    
        override val forceLockReleaseAfter: Duration = Duration.standardMinutes(5)
    }

For ExclusiveTimePeriodLock the holdLockFor timeout allows other apps to claim the lock if it is not renewed for this period

    val exclusiveTimePeriodLock = new ExclusiveTimePeriodLock {

        override def repo: LockRepository = repo //The repo created before

        override def lockId: String = "<something unique for the operation>"

        override val holdLockFor: Duration = Duration.standardMinutes(5)
    }
  1. Use the LockKeeper or ExclusiveTimePeriodLock to execute the code
 lockKeeper.tryLock { 
    // This will be executed on one application only
 }
 exclusiveTimePeriodLock.tryToAcquireOrRenew {
    // This will be executed on one application only
 }

The function in LockKeeper and ExclusiveTimePeriodLock accepts anything that returns a Future[T] tryLock and tryToAcquireOrRen will return the result in an Option. If it was not possible to acquire the lock, None is returned

def tryLock[T](body: => Future[T]): Future[Option[T]] 
def tryToAcquireOrRenew[T](body: => Future[T]): Future[Option[T]]

Installing

Include the following dependency in your SBT build

resolvers += Resolver.bintrayRepo("hmrc", "releases")

libraryDependencies += "uk.gov.hmrc" %% "mongo-lock" % "x.x.x"

License

This code is open source software licensed under the Apache 2.0 License.