diff --git a/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/keys.scala b/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/keys.scala index a516240f..7236efbd 100644 --- a/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/keys.scala +++ b/modules/effects/src/main/scala/dev/profunktor/redis4cats/algebra/keys.scala @@ -33,7 +33,7 @@ trait KeyCommands[F[_], K] { def expireAt(key: K, at: Instant): F[Boolean] def expireAt(key: K, at: Instant, expireExistenceArg: ExpireExistenceArg): F[Boolean] def objectIdletime(key: K): F[Option[FiniteDuration]] - def ttl(key: K): F[Option[FiniteDuration]] + def persist(key: K): F[Boolean] def pttl(key: K): F[Option[FiniteDuration]] // restores a key with the given serialized value, previously obtained using DUMP without a ttl def restore(key: K, value: Array[Byte]): F[Unit] @@ -46,4 +46,6 @@ trait KeyCommands[F[_], K] { @deprecated("In favor of scan(cursor: KeyScanCursor[K], scanArgs: ScanArgs)", since = "0.10.4") def scan(cursor: Long, scanArgs: ScanArgs): F[KeyScanCursor[K]] def scan(previous: KeyScanCursor[K], scanArgs: ScanArgs): F[KeyScanCursor[K]] + def ttl(key: K): F[Option[FiniteDuration]] + } diff --git a/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala b/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala index 5625a1d0..38abb714 100644 --- a/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala +++ b/modules/effects/src/main/scala/dev/profunktor/redis4cats/redis.scala @@ -539,8 +539,8 @@ private[redis4cats] class BaseRedis[F[_]: FutureLift: MonadThrow: Log, K, V]( case d => FiniteDuration(d, units).some } - override def ttl(key: K): F[Option[FiniteDuration]] = - async.flatMap(_.ttl(key).futureLift.map(toFiniteDuration(TimeUnit.SECONDS))) + override def persist(key: K): F[Boolean] = + async.flatMap(_.persist(key).futureLift.map(x => Boolean.box(x))) override def pttl(key: K): F[Option[FiniteDuration]] = async.flatMap(_.pttl(key).futureLift.map(toFiniteDuration(TimeUnit.MILLISECONDS))) @@ -569,6 +569,9 @@ private[redis4cats] class BaseRedis[F[_]: FutureLift: MonadThrow: Log, K, V]( override def scan(previous: KeyScanCursor[K], scanArgs: ScanArgs): F[KeyScanCursor[K]] = async.flatMap(_.scan(previous.underlying, scanArgs.underlying).futureLift.map(KeyScanCursor[K])) + override def ttl(key: K): F[Option[FiniteDuration]] = + async.flatMap(_.ttl(key).futureLift.map(toFiniteDuration(TimeUnit.SECONDS))) + /******************************* Transactions API **********************************/ // When in a cluster, transactions should run against a single node. diff --git a/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala b/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala index 2793899f..45b64e94 100644 --- a/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala +++ b/modules/tests/src/test/scala/dev/profunktor/redis4cats/TestScenarios.scala @@ -262,6 +262,12 @@ trait TestScenarios { self: FunSuite => _ <- IO(assertEquals(h, true)) c <- redis.ttl("f1") _ <- IO(assert(c.nonEmpty)) + persisted <- redis.persist("f1") + _ <- IO(assert(persisted)) + noTTL <- redis.ttl("f1") + _ <- IO(assert(noTTL.isEmpty)) + //reset + _ <- redis.expire("f1", 10.seconds) d <- redis.pttl("f1") _ <- IO(assert(d.nonEmpty)) _ <- IO(assert(d.exists(_ <= 10.seconds)))