Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Dec 06 22:35
    mergify[bot] labeled #628
  • Dec 06 22:34
    scala-steward closed #617
  • Dec 06 22:34
    scala-steward commented #617
  • Dec 06 22:34
    scala-steward opened #628
  • Dec 04 04:53

    mergify[bot] on 1.x

    Update sbt-scalafmt to 2.4.5 Merge pull request #627 from sc… (compare)

  • Dec 04 04:53
    mergify[bot] closed #627
  • Dec 04 04:45
    mergify[bot] labeled #627
  • Dec 04 04:44
    scala-steward closed #620
  • Dec 04 04:44
    scala-steward commented #620
  • Dec 04 04:44
    scala-steward opened #627
  • Nov 30 07:43
    hughsimpson edited #626
  • Nov 30 03:58
    mergify[bot] closed #625
  • Nov 30 03:58

    mergify[bot] on 1.x

    Update cats-effect, cats-effect… Merge branch 'series/1.x' into … Update cats-effect, cats-effect… and 1 more (compare)

  • Nov 30 03:50
    scala-steward synchronize #625
  • Nov 29 17:50
    hughsimpson opened #626
  • Nov 28 07:36

    mergify[bot] on 1.x

    Update cats-core, cats-testkit … Merge pull request #624 from sc… (compare)

  • Nov 28 07:36
    mergify[bot] closed #624
  • Nov 28 07:30
    mergify[bot] labeled #625
  • Nov 28 07:30
    scala-steward opened #625
  • Nov 28 07:28
    mergify[bot] labeled #624
Gabriel Volpe
@gvolpe:matrix.org
[m]
ha! awesome @catostrophe I am just getting started with CE3 so really I wasn't aware Dispatcher depends on in the inner Supervisor
I'll have a look at the PR in a few mins, on a few meetings now
catostrophe
@catostrophe

I just tried to wrap AsyncConnectionPoolSupport in F[_] to get a Resource[F, () => Resource[F, RedisCommand[F, K, V]]] but I couldn't since some constructor in redis4cats is private. So I probably should make a PR.

@gvolpe:matrix.org have you considered providing a functional API for pooling? Are there any nuances I should know before starting doing it?

Gabriel Volpe
@gvolpe:matrix.org
[m]
λoλcat: wasn't really aware of it, seems like it could be a good addition to the library :)
Ben Plommer
@bplommer
@gvolpe:matrix.org v1.0.1 doesn't seem to be on Maven Central :|
Ben Plommer
@bplommer
Oh nvm, that's a draft release
Gabriel Volpe
@gvolpe:matrix.org
[m]
Hehe no problems, I guess it's time to make a new RC
Ben Plommer
@bplommer
:+1:
Ben Plommer
@bplommer
splendid
Nacho Castillo
@nachocodexx
Hi, I'm struggling to get RedisTransaction working, I get the following message: No implicit arguments of type: WitnessFilter[HList]
  def saveCreatedEvent(c: Node.Created)(implicit C:DefaultConfig) = client.use{ cmd=>
    val tx = RedisTransaction(cmd)
    val payload =  c.payload
    val tagCmd  = generateSetCommand(cmd,c.nodeId,"tag")(payload.tag)
    val commands= HList.fromList(tagCmd::Nil)
    tx.filterExec(commands)
  }
Gabriel Volpe
@gvolpe:matrix.org
[m]
@nachocodexx: I believe that Hlist.fromList never worked. Can you please raise an issue?
Gabriel Volpe
@gvolpe:matrix.org
[m]

@nachocodexx: why are you using HList.fromList though? Isn't that tagCmd a single command? You can basically do

val commands = tagCmd :: HNil

Or if you really need a dynamic list, you can use this hack but it requires knowing the types to help the compiler

 val commands = HList.fromList(List(IO.unit, IO.pure("hi"))).asInstanceOf[IO[Unit] :: IO[String] :: HNil]
Nacho Castillo
@nachocodexx
Hi @gvolpe:matrix.org ,I'm wanna run multiple commands and I tried to run in a transaction but i faced this problem.

if I follow the documentation example and create the commands list using (::) operator and HNil, the result is the same:

val commands=  tagCmd::ipAddressCmd::HNil

\ No implicit arguments of type: WitnessFilter[HCons[IO[Unit], HCons[IO[Unit], hlist.HNil.type]]]

Nacho Castillo
@nachocodexx
Which should I import in my code to get that implicit value ?
Nacho Castillo
@nachocodexx
I used RedisTransaction.exec insted of RedisTransaction.filterExec method and works like a charm
catostrophe
@catostrophe
@gvolpe:matrix.org @bplommer any blockers on the road to 1.0.0 final?
Gabriel Volpe
@gvolpe:matrix.org
[m]
There are two issues (streaming offset and hlist.fromList) I'd like to get fixed before 1.0.0 but I barely have any time these days :(
Yisrael Union
@yisraelU
is there support for authentication , I cannot find it in the documentation
Artem Sholokhov
@sholokhov
hi @gvolpe:matrix.org ! is there any plans to back port underlying dependency updates into 0.xx series? specifically I'm interested in lettuce-core 6.1.2 that seems to be merged only in 1.xx. They have fixed a nasty bug (lettuce-io/lettuce-core#1706) that we are facing in prod, but we didn't event start migrating to CE3 yet, so can't really take a 1.xx snapshot
1 reply
Ben Plommer
@bplommer
I think you should be able to manually update your app’s lettuce dependency with the current r4c version?
Artem Sholokhov
@sholokhov
thanks @bplommer , will try to swap the binary and see if its bin compatible
ankusharya
@ankusharya
Hi, I am new to redis4cats. I am trying with doc example Stream Example but it is not working. Redis4cats version 0.13.1 . Am i missing anything?
Dmitry Svetlakov
@ae0n
HI folks. I'm trying to use Transactions and found that commands in a transaction run in random order. Is it expected behaviour? I've created a small code snippet to demonstrate the problem https://gist.github.com/ae0n/8a90b0e11c8621978d09ea95ad608585
I've tried redis4cats 0.14.0 and 1.0.0
Gabriel Volpe
@gvolpe:matrix.org
[m]

Yeah transactions are quite tricky to get working in an asynchronous fashion. I recommend staying away from them, limit yourself to write-only commands where order does not matter, or use the Sync API from Lettuce directly for now.

The reason is that every REDIS command has to be scheduled to run in the same thread but the scheduler does not guarantee order.

Dmitry Svetlakov
@ae0n
Hi Gabriel, thank you for the answer
Dmitry Svetlakov
@ae0n
maybe it's worth to add this into the documentation, because now it's not clear from it
shoryusauce
@shoryusauce

Hi I just tried this, from the official website doc:

import cats.effect._
import cats.implicits._
import dev.profunktor.redis4cats.Redis
import dev.profunktor.redis4cats.effect.Log.Stdout._

object QuickStart extends IOApp.Simple {

  def run: IO[Unit] =
    Redis[IO].utf8("redis://localhost").use { redis =>
      for {
        _ <- redis.set("foo", "123")
        x <- redis.get("foo")
        _ <- redis.setNx("foo", "should not happen")
        y <- redis.get("foo")
        _ <- IO(println(x === y)) // true
      } yield ()
    }

}

this didn't work for me with 1.0.0. but it worked for me with 0.13.1 apparently I am missing some MkRedis[IO] implicit. where do I get that from?

4 replies
Gabriel Volpe
@gvolpe:matrix.org
[m]
Notice that the documentation is always compiled against the latest version based on CE3: https://redis4cats.profunktor.dev/quickstart.html
@shoryusauce: it also compiles on Scastie -> https://scastie.scala-lang.org/hwnV2n4mSgOuFbxQ3Vo4cA
Gabriel Volpe
@gvolpe:matrix.org
[m]
@shoryusauce: that's very strange, can you create a minimal Scastie with the exact versions you're using? You can also try looking at the dependency tree, probably some mixed-up versions in scope.
quanganhtran
@quanganhtran
I'm trying to manually instrument Lettuce with opentracing by https://github.com/opentracing-contrib/java-redis-client
How to I get to, and swap out, the underlying RedisConnection or RedisCommands (of lettuce)?
@gvolpe:matrix.org hopefully you are still around
Dmitry Svetlakov
@ae0n
I've managed to extend RedisCommand with small hack. I've create a file with package package dev.profunktor.redis4cats then I've implemented there new trait with commands I need that was an extension of RedisCommands then I've created a client itself by extending BaseRedis and my commands. Also I've made a custom generator of Redis resource
package dev.profunktor.redis4cats

import cats.effect.{Concurrent, ContextShift, Resource}
import cats.implicits._
import dev.profunktor.redis4cats.connection.{RedisClient, RedisConnection, RedisStatefulConnection}
import dev.profunktor.redis4cats.data.RedisCodec
import dev.profunktor.redis4cats.effect.JRFuture.FutureLiftOps
import dev.profunktor.redis4cats.effect.{JRFuture, Log, RedisExecutor}

trait ExtRedisCommands[F[_], K, V] extends RedisCommands[F, K, V] {

  def renamenx(key: K, newKey: K): F[Boolean]

}

class ExtRedis[F[_]: Concurrent: ContextShift: RedisExecutor: Log, K, V](
    conn: RedisConnection[F, K, V],
    cluster: Boolean
) extends BaseRedis[F, K, V](conn, cluster)
    with ExtRedisCommands[F, K, V] {

  def renamenx(key: K, newKey: K): F[Boolean] = {
    async
      .flatMap(c => RedisExecutor[F].delay(c.renamenx(key, newKey)))
      .futureLift
      .map(x => Boolean.box(x))
  }

}

object ExtRedis {

  /**
    * Modified version of dev.profunktor.redis4cats.Redis.simple
    */
  def simple[F[_]: Concurrent: ContextShift: Log, K, V](uri: String, codec: RedisCodec[K, V]): Resource[F, ExtRedisCommands[F, K, V]] = {
    RedisClient[F].from(uri).flatMap(fromClient(_, codec))
  }

  /**
    * Modified version of dev.profunktor.redis4cats.Redis.fromClient
    */
  def fromClient[F[_]: Concurrent: ContextShift: Log, K, V](
      client: RedisClient,
      codec: RedisCodec[K, V]
  ): Resource[F, ExtRedisCommands[F, K, V]] =
    RedisExecutor.make[F].flatMap { implicit redisExecutor =>
      val (acquire, release) = {
        val acquire = JRFuture
          .fromConnectionFuture(
            RedisExecutor[F].delay(client.underlying.connectAsync(codec.underlying, client.uri.underlying))
          )
          .map(c => new ExtRedis(new RedisStatefulConnection(c), false))

        val release: ExtRedis[F, K, V] => F[Unit] = c => Log[F].info(s"Releasing Commands connection: ${client.uri.underlying}") *> c.conn.close

        (acquire, release)
      }
      Resource.make(acquire)(release).widen
    }

}
quanganhtran
@quanganhtran
thanks for the tip! I'm trying to use fromUnderlyingWithUri and pass a custom lettuce client but this method skip the whole acquire-and-release part, which I can't say I know much about. I'll check it out your approach
Gabriel Volpe
@gvolpe:matrix.org
[m]

@quanganhtran: it seems possible to add support for it in the library. IIUC we need a RedisTracingStatefulConnection as another implementation of https://github.com/profunktor/redis4cats/blob/series/1.x/modules/core/src/main/scala/dev/profunktor/redis4cats/connection/RedisConnection.scala#L36 but it'll have to be done in a separate module to avoid an extra dependency in core.

Then we can create special constructors for tracing, also in a redis4cats-tracing module. E.g.

object TracingRedis {
  def utf8(uri: String, config: TracingConfiguration): Resource[F, RedisCommands[F, String, String]] = ???
}

Feel free to submit a feature request or even better a PR :)

The code that acquires the connection and releases it needs to be adapted to take the a UnderlyingConnection => RedisConnection or something like that but seems doable.
Jonathan Lecointe
@jihhel

Hello @gvolpe:matrix.org !
I'm new to using this lib, and am trying to fetch data from my db by using the eval method :

def eval(script: String, output: ScriptOutputType[V], keys: List[K], values: List[V]): F[output.R]

My problem is : the output and the input value both must have the same type V, why is that ? My input values are strings, but for the output values I would like to fetch something else.
Is there a way to bypass this constraint ? I think that it should be possible, given the underlying lettuce function

<T> Command<K, V, T> eval(byte[] script, ScriptOutputType type, K[] keys, V... values) {
        LettuceAssert.notNull(script, "Script " + MUST_NOT_BE_NULL);
        LettuceAssert.notNull(type, "ScriptOutputType " + MUST_NOT_BE_NULL);
        LettuceAssert.notNull(keys, "Keys " + MUST_NOT_BE_NULL);
        LettuceAssert.notNull(values, "Values " + MUST_NOT_BE_NULL);
        CommandArgs<K, V> args = new CommandArgs<>(codec);
        args.add(script).add(keys.length).addKeys(keys).addValues(values);
        CommandOutput<K, V, T> output = newScriptOutput(codec, type);
        return createCommand(EVAL, output, args);
    }

Thanks in advance for any answer :)

1 reply
Swoorup Joshi
@Swoorup
hello, is the documentation outdated?
i can no longer run the pubsub example in 1.0.0
nvm i didn't download the correct package facepalm
Gabriel Giussi
@gabrielgiussi

Hello, I have a newbie question. How can I retry getting a Redis connection? (I think the question is more general and applies to every Resource but since I'm trying redis4cats I though about asking here).

  def redisConnection: Resource[IO, RedisCommands[IO, String, Long]] = Redis[IO].simple("redis://redis-1:6379", Codecs.derive(RedisCodec.Ascii,stringLongEpi))
    .handleErrorWith {
      _: Throwable => Resource.liftK(IO.println("attempting to connect to redis") *> IO.sleep(5.seconds)).flatMap(_ => redisConnection)
    }

This does the trick in the sense that will keep retrying getting the connection, but when the program stops I see a cascade of calls to the release function (i.e. a bunch of Releasing Redis connection: RedisURI(redis://redis-1) are logged). I even got this warn from netty

io.netty.util.HashedWheelTimer - You are creating too many HashedWheelTimer instances. HashedWheelTimer is a shared resource that must be reused across the JVM, so that only a few instances are created.

So I guess with my attempt the HashedWheelTimer#finalize is not being called after each attempt.

1 reply
Muhammad Tabaza
@Tabzz98
Hello
Is there a way to execute raw commands? I'm trying to use LMPOP
2 replies