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)
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.