2017-06-20 9 views
0

私は共同製図ボードを作成しています(例:r/place):ユーザーがいつでも変更できるピクセルグリッドがあり、ピクセルアップデートが他のすべてのユーザーはオンラインです。私はピクセル変更をブロードキャストするためにフェニックスチャンネルを使用したいと思います。フェニックスチャンネル(またはその他のpubsub)に参加中にアプリケーションの状態を同期させる

私の質問は、どのようにになるのですか。は、ユーザーがサービスに接続するときに現在のアプリケーションの状態を送信します。

現在、私は描画ボードの状態を保持しているETSテーブルを持っています。ピクセル書き込みをブロードキャストする前に、このテーブルをMyChannel.handle_in/3に更新することができます。

私の恐怖は間でMyChannel.joinで現在の状態を読み取り、ユーザは、異なるプロセス状態を更新し、フェニックスによってチャンネルに登録されていることです。

ユーザーはアプリケーション状態の古いバージョンを取得し、まだ購読していないため、チャネル経由で更新を取得しません。

これを解決するには、現在の状態を原子的に読み取ってからpubsubにサブスクライブする方法が必要であり、メッセージがその期間のETSテーブルまたはチャネルに書き込まれないようにする必要があると思います。私はロックを推測する?それはElixireyですか、別の方法ですか?

答えて

0

この質問を書いているうちに、私はChris McCoordのElixirConf 2015 training materialsを見ました。私はその例で同じ競争条件があると思ったが、そうではないことが判明した!そのチャネルはソリューションを保持します。 Channel.join機能プロセスにおけるその例で

は、それ自身送信:アプリケーションの状態を読み取り、送信する:(サブスクライブされた後)に トリガhandle_info({after_join ...})であろうメッセージ、after_joinそれをユーザーに知らせる。

キーは、購読後にアプリケーションの状態を照会することです。

また、公開前に常に状態を変更します。

私は24点の可能な順序付けのあらゆる経たので、私はいつも言って

:状態を読ん

  • 状態を変異、
  • チャンネルにチャンネル
  • 出版に加入

サブスクライブ後の状態を確認し、 出版前の状態を解説し、データが失われないことが保証されました。 Here my work in a gist

これは、状態の変化が2回見られる4つの可能な状態につながりますが、データ損失よりも扱いが簡単です。

関連する問題