scalalock-api

Distributed Lock library in scala. currently supported persistence stores: mongodb - depending on mongo-scala-driver

License

License

Categories

Categories

Scala Languages
GroupId

GroupId

com.weirddev
ArtifactId

ArtifactId

scalalock-api_2.12
Last Version

Last Version

1.0.6
Release Date

Release Date

Type

Type

jar
Description

Description

scalalock-api
Distributed Lock library in scala. currently supported persistence stores: mongodb - depending on mongo-scala-driver
Project URL

Project URL

https://github.com/wrdv/scalalock
Project Organization

Project Organization

WeirdDev
Source Code Management

Source Code Management

https://github.com/wrdv/scalalock

Download scalalock-api_2.12

How to add to project

<!-- https://jarcasting.com/artifacts/com.weirddev/scalalock-api_2.12/ -->
<dependency>
    <groupId>com.weirddev</groupId>
    <artifactId>scalalock-api_2.12</artifactId>
    <version>1.0.6</version>
</dependency>
// https://jarcasting.com/artifacts/com.weirddev/scalalock-api_2.12/
implementation 'com.weirddev:scalalock-api_2.12:1.0.6'
// https://jarcasting.com/artifacts/com.weirddev/scalalock-api_2.12/
implementation ("com.weirddev:scalalock-api_2.12:1.0.6")
'com.weirddev:scalalock-api_2.12:jar:1.0.6'
<dependency org="com.weirddev" name="scalalock-api_2.12" rev="1.0.6">
  <artifact name="scalalock-api_2.12" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.weirddev', module='scalalock-api_2.12', version='1.0.6')
)
libraryDependencies += "com.weirddev" % "scalalock-api_2.12" % "1.0.6"
[com.weirddev/scalalock-api_2.12 "1.0.6"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.12.7
org.slf4j : slf4j-api jar 1.7.25

test (3)

Group / Artifact Type Version
ch.qos.logback : logback-classic jar 1.2.3
org.specs2 : specs2-core_2.12 jar 4.3.4
org.specs2 : specs2-mock_2.12 jar 4.3.4

Project Modules

There are no modules declared in this project.

Scalalock Maven Central

Distributed lock library in scala. based on mongodb (using reactivemongo or mongo-scala-driver)

consists of 3 modules:

  • scalalock-api - contains the api and the locking logic
  • scalalock-mongo - an api implementation using mongodb as the lock persistence store. implementation is dependant on mongo-scala-driver.
  • scalalock-reactivemongo - an alternative api implementation using reactivemongo as the mongodb driver. implementation is dependant on reactivemongo.

Usage

  1. Add dependencies to build.sbt:
  • Option A - if you're using mongo-scala-driver
    libraryDependencies ++= Seq(
      "com.weirddev" %% "scalalock-api" % "1.0.6",
      "com.weirddev" %% "scalalock-mongo" % "1.0.6"
    )
  • Option B - if you're using reactivemongo
    libraryDependencies ++= Seq(
      "com.weirddev" %% "scalalock-api" % "1.0.6",
      "com.weirddev" %% "scalalock-reactivemongo" % "1.0.6"
    )
  1. wrap the block that should be synchronized across all nodes in cluster with Lock#acquire() method call

    • For scalalock-mongo (based on mongo-scala-driver)
    import com.mongodb.ConnectionString
    import com.weirddev.scalalock.mongo.MongoDistributedLock
    import org.mongodb.scala.{MongoClient, MongoClientSettings, MongoDatabase}
    import scala.concurrent.Future
    import scala.concurrent.duration._
    
    protected val db: MongoDatabase = MongoClient(MongoClientSettings.builder()
        .applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
        .build()).getDatabase("test")
    
    val distLock:Lock = new MongoDistributedLock(db)
    
    distLock.acquire("some_task_id", 10 minutes){
      Future{
        println("this block needs to execute in isolation across all application nodes in cluster")
        Thread.sleep(5000)
        "Task Completed"
      }
    }
    • Alternatively, using scalalock-reactivemongo (based on org.reactivemongo)
    import com.weirddev.scalalock.reactivemongo.ReactiveMongoDistributedLock
    import reactivemongo.api.{DefaultDB, MongoConnection, MongoDriver}
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.Future
    import scala.concurrent.duration._
    
    private val mongoUri: String = "mongodb://localhost:27017/test"
      val driver = new MongoDriver
      val database: Future[DefaultDB] = for {
        uri <- Future.fromTry(MongoConnection.parseURI(mongoUri))
        con = driver.connection(uri)
        dn <- Future(uri.db.get)
        db <- con.database(dn)
      } yield db
    
      val distLock = new ReactiveMongoDistributedLock(database)
    
    distLock.acquire("some_task_id", 10 minutes){
      Future{
        println("this block needs to execute in isolation across all application nodes in cluster")
        Thread.sleep(5000)
        "Task Completed"
      }
    }
    • A simpler alternative using scalalock-reactivemongo in Play! Framework (add a dependency on reactivemongo play, i.e. "org.reactivemongo" %% "play2-reactivemongo" % "0.16.5-play26" )
    import com.weirddev.scalalock.reactivemongo.ReactiveMongoDistributedLock
    import scala.concurrent.{ExecutionContext, Future}
    import scala.concurrent.duration._
    import javax.inject.Inject
    import play.modules.reactivemongo.ReactiveMongoApi
    
    class MyRepository @Inject()(override val reactiveMongoApi: ReactiveMongoApi)(implicit val ec: ExecutionContext){
      val distLock = new ReactiveMongoDistributedLock(reactiveMongoApi.database)
    
      distLock.acquire("some_task_id", 10 minutes){
        Future{
          println("this block needs to execute in isolation across all application nodes in cluster")
          Thread.sleep(5000)
          "Task Completed"
        }
      }
    }
  2. If you want to use the lock to synchronize task execution globally in a cluster and mandating a minimal interval - pass the releaseLockWhenDone as false. This will keep the lock state as LOCKED even after task completion. Effectively keeping the lock until expiration - as set by the expire param. example:

      val result = mongoDistLock.acquire(resourceId =  "test_task", expire = 30 minutes,releaseLockWhenDone = false){
          println("After this block finishes to execute, the lock will retain for 30 minutes before any other task using resource id - test_task - could run again")
          Thread.sleep(5000)
           "Done"
      }

    For other usage scenarios, review the integrative test code

Contributing/Developing

Welcomed :) - Please refer to CONTRIBUTING.md file.

License

Copyright (c) 2016 - 2019 WeirdDev. Licensed for free usage under the terms and conditions of Apache V2 - Apache V2 License.

com.weirddev

WeirdDev

Versions

Version
1.0.6
1.0.5
1.0.4