binkabir
binkabir

Reputation: 154

creating a RedisClient from a typed akka behavior

Im trying to use this scala redis library etaty which needs an implicit akka.actor.ActorSystem when creating it's RedisClient object. I used the context.system.classicSystem in the Behaviors.setup method to provide the needed implicit.

Here is my code

 
def apply(): Behavior[Command] = Behaviors.setup { context =>
    implicit val system  = context.system
    implicit val classic  = context.system.classicSystem

   lazy val redis  = RedisClient(
      host = host,
      port = port
    )

However, I getting this errors in my logs.

java.lang.UnsupportedOperationException: cannot create top-level actor [RedisClient-$a] from the outside on ActorSystem with custom user guardian
    at akka.actor.ActorSystemImpl.actorOf(ActorSystem.scala:895)
    at redis.RedisClientActorLike.<init>(Redis.scala:41)
    at redis.RedisClient.<init>(Redis.scala:86)
    at ng.logicbud.deidara.core.db.redis.RedisDbService$.redis$lzycompute$1(RedisDbService.scala:34)
    at ng.logicbud.deidara.core.db.redis.RedisDbService$.redis$1(RedisDbService.scala:34)
    at ng.logicbud.deidara.core.db.redis.RedisDbService$.$anonfun$apply$2(RedisDbService.scala:62)
    at akka.actor.typed.internal.BehaviorImpl$ReceiveMessageBehavior.receive(BehaviorImpl.scala:152)
    at akka.actor.typed.Behavior$.interpret(Behavior.scala:274)
    at akka.actor.typed.Behavior$.interpretMessage(Behavior.scala:230)
    at akka.actor.typed.internal.adapter.ActorAdapter.handleMessage(ActorAdapter.scala:129)
    at akka.actor.typed.internal.adapter.ActorAdapter.aroundReceive(ActorAdapter.scala:106)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:577)
    at akka.actor.ActorCell.invoke(ActorCell.scala:547)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270)
    at akka.dispatch.Mailbox.run(Mailbox.scala:231)
    at akka.dispatch.Mailbox.exec(Mailbox.scala:243)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

Upvotes: 0

Views: 372

Answers (1)

johanandren
johanandren

Reputation: 11479

This is because the redis client wants to create a top level actor under /user which is not possible with a typed actor system because there the /user actor is yours and the only one who is allowed to spawn children of that actor is itself.

The etaty library should be updated to not require doing that (for example return an actor for you to start, or use systemActorOf to start its own internal actors). You can however work around this by using a classic actor system in your app, and adapting to the typed APIs instead.

Upvotes: 1

Related Questions