gpt4 book ai didi

concurrency - 为协调写入/读取选择正确的 Clojure 引用类型

转载 作者:行者123 更新时间:2023-12-04 05:30:20 26 4
gpt4 key购买 nike

我正在为 Campfire 开发一个聊天机器人,它将当前用户列表保存在一个原子中,(defonce users (atom {})) .

我最初选择这种引用类型是因为它的简单性,直到现在它都运行良好,但这可能需要改变。

  • 营火送EnterMessageLeaveMessage事件到流 API。我的机器人通过从 Campfire API 获取当前用户列表来对这些使用react,然后调用 reset!users带有新列表的原子。
  • 这些相同的进入/离开事件会触发随机交互,例如从 users 中随机选择一个用户。原子并问它一个问题。

  • 问题

    上面的数字 2 经常问刚离开的用户或从未问过刚进入的用户,因为 users原子还没有被 !reset .我想我需要使用 ref ,但是 these docs说“作家永远不会阻止通勤者或读者。”问题是,我希望那个作家阻止我的读者,对吧?!

    最佳答案

    ref s 主要用于协调访问多个数据结构,如果您只有一个身份(用户列表),那么 refs 的主要优势对您来说并不是真正的优势,尽管它也不是真正的问题。 Refs 也有成本,因为交易可能会运行多次,所以如果您的操作有发送消息等副作用,那么在交易重试时消息可能会发送两次。您可以通过使用 ref 和代理来解决这个问题,因为从事务发送到代理的消息保证只发送一次,并且只发送最终提交的值。
    在您的情况下,您可以通过以下方式做得很好:

  • 继续使用原子
  • 使用类似 (swap! users assoc name user) 的东西以增量方式构建用户列表。
  • 使用 watch function在原子上处理状态变化,因为 watch 会捕捉每个状态变化。


  • 切换到引用
  • 使用代理将实际消息发送给用户。
  • 使用 watch 可以使这更简单,但不是必需的。

  • 引用“作家永远不会阻止通勤者或读者。”尽管值得解释一下,但可能与您没有直接关系。在单个 ref 的情况下,一个简单地读取 ref 值的线程从不等待,它获取当前值并继续。当有多个 ref 时,它可以在一个事务中同时读取它们,并保证它将从它们两者中获得一组一致的值,或者将重新运行,直到它确实获得一组一致的值。需要更新值的线程如果没有获得一致的值集,同样需要重新运行,除非它们使用 commute函数来更新它们,在这种情况下,STM 将知道提交新值是安全的,即使其他线程也对值执行了相同(或可交换)的操作。

    关于concurrency - 为协调写入/读取选择正确的 Clojure 引用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12714635/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com