akka:共享可变状态

发布于 2024-12-03 06:13:11 字数 580 浏览 1 评论 0原文

我需要有一个很少改变的全局变量(单例)。实际上它只会在 actor 重新启动并重新初始化变量时发生变化。由于我无法在伴生对象中使用 singleton val 来执行此操作,因此我必须将其声明为 var (可变)。

object UserDatabase {
    var dbConnection = "" // initializing db connection
}

我读到的许多指南总是反对共享可变状态。因此,我将变量移至类并使用消息传递来检索变量。

class UserDatabase extends Actor{
    val dbConnection = "" // initializing db connection locally
    def receive = {case GetConnection => self.reply(dbConnection)}
}

问题是,dbConnection 被许多..许多参与者非常频繁地访问,并且连续发送消息会降低性能(因为 akka 会一一处理邮箱)。

我不知道如何在不牺牲性能的情况下做到这一点。有什么想法吗?

I need to have one global variable (singleton) that will change very infrequently. Actually it only changes when the actor restarts, and reinitialize the variable. Since I cannot do this with singleton val in companion object, I have to declare it as a var (mutable).

object UserDatabase {
    var dbConnection = "" // initializing db connection
}

Many guidelines that I read always go against sharing a mutable state. So I move the variable to class and use message passing to retrieve the variable.

class UserDatabase extends Actor{
    val dbConnection = "" // initializing db connection locally
    def receive = {case GetConnection => self.reply(dbConnection)}
}

Problem is, dbConnection is accessed very frequently by many .. many actors, and continuously sending message will reduce performance (since akka process mailbox one by one).

I don't see how I can do this without sacrificing performance. Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深海夜未眠 2024-12-10 06:13:11

首先,您是否真正测量/注意到性能下降?由于消息传递是轻量级的,因此对于您的应用程序来说可能足够快。

那么,一个可能的解决方案是:如果“全局”状态很少写入,但访问很频繁,则可以选择推送策略。每次更改时,UserDatabase actor 都会将更新后的值发送给感兴趣的 actor。然后,您可以使用发布/订阅方法、依赖参与者注册、使用参与者池等。

class UserDatabase extends Actor{
    var dbConnection = "" // initializing db connection locally
    def receive = {
      case SetConnection( newConnection ) if dbConnection != newConnection => {
        dbConnection = newConnection
        sendUpdatedConnection(); // sends the change to every relevant actor
      }
    }
}

First of all, have you actually measure/notice performance reduction ? Since messaging is lightweight, perhaps it's fast enough for your application.

Then, a possible solution: If the "global" state is written rarely, but accessed very often, you can choose a push strategy. Every time it changes, the UserDatabase actor will send the updated value to interested actors. You can then use a publish/subscribe approach, rely on the actor register, use a pool of actors, etc.

class UserDatabase extends Actor{
    var dbConnection = "" // initializing db connection locally
    def receive = {
      case SetConnection( newConnection ) if dbConnection != newConnection => {
        dbConnection = newConnection
        sendUpdatedConnection(); // sends the change to every relevant actor
      }
    }
}
灵芸 2024-12-10 06:13:11

如果您在任何情况下都不需要经常使用该变量,那么将其设为 java.lang.concurrent.atomic.AtomicReference 或将其每次访问包装在其中可能会更简单、更高效一个同步块(在变量上)。演员并不总是让事情变得更容易和更安全,只是通常如此。

If you don't need to use the variable very often in any case, it might be simpler and more efficient to make it a java.lang.concurrent.atomic.AtomicReference or wrap every access of it in a synchronized block (on the variable). Actors don't always make things easier and safer, just usually.

请恋爱 2024-12-10 06:13:11
  1. 创建许多参与者作为 RoundRobinRouter 的路由。
  2. 让每个参与者处理一个连接并实际处理数据库逻辑。
  1. Create many actors as routees of a RoundRobinRouter.
  2. Make each actor handle a connection and actually handling the DB logic.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文