Skip to content

Instantly share code, notes, and snippets.

@abhandaru
Last active April 23, 2019 23:44
Show Gist options
  • Save abhandaru/712d4f2bfd360fe29b7ecefa81ac9c3f to your computer and use it in GitHub Desktop.
Save abhandaru/712d4f2bfd360fe29b7ecefa81ac9c3f to your computer and use it in GitHub Desktop.
// Using Rediscala library here.
import redis.RedisClient
import scala.concurrent.Future
import java.util.UUID
case class RedisLockedException(key: String) extends Exception(s"Resource '${key}' is in use.")
// This is based on the following Redis locking scheme (single instance):
// https://redis.io/topics/distlock
object RedisLock {
val redisClient: RedisClient
val LockKey = "some/lock/key"
def withLock[T](ttl: Long)(work: => Future[T]): Future[T] = {
val signature = UUID.randomUUID.toString
val didAcquire = redisClient.set(LockKey, signature, NX = true, pxMilliseconds = Some(ttl))
didAcquire.flatMap {
case false => Future.failed(RedisLockedException(LockKey))
case true =>
work.flatMap { result =>
val ownerSignature = redisClient.get[String](LockKey)
val weOwnExistingLock = ownerSignature.map(_ == Some(signature))
weOwnExistingLock.flatMap {
case true => redisClient.del(LockKey).map(_ => result)
case false => Future.successful(result)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment