2

現在のユーザーリストをアトムに保持するCampfireのチャットボットに取り組んでいます(defonce users (atom {}))

私はもともとその単純さのためにこの参照型を選びました、そしてそれは今までうまく機能しました、しかしそれは変更される必要があるかもしれません。

  1. CampfireはイベントをストリーミングAPIに送信EnterMessageします。LeaveMessage私のボットは、Campfire APIから現在のユーザーリストを取得し、新しいリストでアトムを呼び出すことreset!で、これらに反応します。users

  2. usersこれらの同じEnter/Leaveイベントは、アトムからランダムなユーザーを選択して質問するなど、ランダムな相互作用をトリガーします。

問題

上記の2番目の例では、usersアトムがまだ存在していないために、離れたばかりのユーザーに尋ねるか、入ったばかりのユーザーに尋ねることはありません!reset。を使用する必要があると思いますrefが、これらのドキュメントには、「ライターは通勤者やリーダーをブロックすることはありません」と書かれています。

4

1 に答える 1

3

ref■ID(ユーザーリスト)が1つしかない場合、主に複数のデータ構造への調整されたアクセス用に設計されています。refsの主な利点は、実際には問題ではありませんが、実際には利点ではありません。トランザクションが複数回実行される可能性があるという点で、参照にもコストがかかります。そのため、アクションにメッセージの送信などの副作用がある場合、トランザクションの再試行でメッセージが2回送信される可能性があります。トランザクションからエージェントに送信されるメッセージは、最終的にコミットされた値で1回だけ送信されることが保証されているため、refとエージェントの両方を使用してこれを回避できます。

あなたの場合、あなたは次の方法でうまくいくことができます:

また

  • 参照に切り替えます
  • エージェントを使用して、実際のメッセージをユーザーに送信します。
  • 時計を使用すると、これが簡単になる可能性がありますが、必須ではありません。

「作家は通勤者や読者を決してブロックしない」という引用。少し説明する価値はありますが、直接関係がない場合があります。単一のrefの場合、refの値を読み取るだけのスレッドは待機せず、現在の値を取得して続行します。複数の参照がある場合、トランザクション内で両方を読み取り、両方から一貫した値のセットを取得するか、一貫した値のセットを取得するまで再実行されるという保証を取得できます。値を更新する必要があるスレッドは、一貫した値のセットを取得しない場合も同様に再実行する必要があります。ただし、commute関数を使用して値を更新している場合は、STMは新しい値をコミットしても安全であると認識します。他のスレッドも同じ(または可換)操作を値に対して実行しました。

于 2012-10-03T18:56:02.700 に答える