我正在建立一个协作绘图板(例如r / place):有一个像素网格,用户可以随时更改像素更新,并将像素更新传播到所有其他在线用户。我想使用Phoenix Channels来广播像素变化。
我的问题是当用户连接到服务时如何正确发送当前的应用程序状态。
目前我有一个ETS表保持绘图板状态。在广播任何像素写入之前,我可以在MyChannel.handle_in/3
中更新此表。
我担心介于之间读取MyChannel.join
中的当前状态,而用户正在订阅Phoenix的频道,不同的进程会更新状态。
用户将获得应用程序状态的陈旧版本,并且他们尚未订阅,因此他们也不会通过频道获得更新。
要解决这个问题,我想我需要一种方法来自动读取当前状态,然后订阅pubsub,确保在该时间段内没有消息写入ETS表或Channel。我猜一把锁?那是Elixirey,还是有另一种方式?
答案 0 :(得分:1)
在写这个问题时,我看了一下Chris McCoord的ElixirConf 2015 training materials。我认为那个例子中有相同的竞争条件,但事实证明没有!该渠道拥有解决方案。
在该示例中,在Channel.join
函数进程中向自己发送:after_join消息,稍后(在订阅之后)将
触发handle_info({:after_join ...})以读取应用程序状态并将其发送给用户。
关键是在订阅后查询应用程序状态。
并且在发布之前也总是改变状态。
我总是说,因为我经历了以下24种可能的排序:
它确实导致4种可能的情况,其中状态变化被看到两次,但这比数据丢失更容易处理。