2017-06-20 36 views
0

我正在构建一个协作绘图板(例如r/place):有一个像素网格,用户可以随时更改像素更新并传播到所有其他用户在线。我想使用Phoenix Channels来播放像素更改。在加入Phoenix频道(或其他pubsub)时同步应用程序状态

我的问题是关于如何正确当用户连接到服务时发送当前的应用程序状态。

目前我有一个ETS表,其中包含绘图板状态。在广播任何像素写入之前,我可以在MyChannel.handle_in/3中更新此表。

我的恐惧是之间读取当前状态MyChannel.join,并且用户订阅了凤凰卫视,不同的过程更新状态。

用户会得到一个陈旧的应用程序状态版本,他们不会被订阅,所以他们也不会通过频道获得更新。

为了解决这个问题,我想我需要一种方法来自动读取当前状态,然后订阅pubsub,确保在该时间段内没有消息写入ETS表或通道。我猜想一个锁?那是Elixirey,还是有另一种方式?

回答

0

在写这个问题时,我看了一下Chris McCoord的ElixirConf 2015 training materials。我认为在那个例子中有同样的竞赛条件,但事实证明并非如此!该频道拥有解决方案。

在该示例中,在Channel.join功能过程发送本身:after_join消息,其以后(所预订后)将 触发handle_info({:after_join ...})读取应用程序状态,并发送那对用户。

关键是查询订阅后的应用状态。

并且还总是在发布之前更改状态。

我说永远,因为我通过每一个的24级可能的排序中去:

  • 读取时的状态,
  • 变异的状态,
  • 订阅频道
  • 发布到通道

并确认阅读订阅后的状态,加上 u在发布之前对状态进行调整,保证不会丢失数据。 Here my work in a gist

它确实会导致4种可能出现状态变化两次的情况,但这比数据丢失更容易处理。

相关问题