首页 > 解决方案 > 从类型化的 akka 行为创建 RedisClient

问题描述

我试图使用这个 scala redis 库etatyakka.actor.ActorSystem ,它在创建它的 RedisClient 对象时需要一个隐式。我context.system.classicSystem在 Behaviors.setup 方法中使用了提供所需的隐式。

这是我的代码

 
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
    )

但是,我在日志中收到此错误。

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)

标签: scalaredisakkaakka-typed

解决方案


这是因为 redis 客户端想要在 /user 下创建一个顶级演员,这对于类型化的演员系统是不可能的,因为 /user 演员是你的,并且唯一允许产生该演员的孩子的人就是它自己。

etaty 库应该更新为不需要这样做(例如返回一个演员供您启动,或用于systemActorOf启动它自己的内部演员)。但是,您可以通过在您的应用程序中使用经典的演员系统来解决这个问题,并改为适应类型化的 API。


推荐阅读