Синхронизация состояния приложения при присоединении к каналу Phoenix (или другому pubsub)

Я создаю совместную чертежную доску (например, r/place): есть сетка пикселей, которую пользователи могут изменять в любое время, и обновления пикселей распространяются на всех других пользователей в сети. Я хочу использовать каналы Phoenix для трансляции изменений пикселей.

Мой вопрос о том, как правильно отправить текущее состояние приложения, когда пользователь подключается к службе.

В настоящее время у меня есть таблица ETS, содержащая состояние чертежной доски. Я могу обновить эту таблицу в MyChannel.handle_in/3 перед трансляцией записи любого пикселя.

Я боюсь, что между чтением текущего состояния в MyChannel.join и подпиской пользователя на канал Phoenix другой процесс обновляет состояние.

Пользователь получит устаревшую версию состояния приложения, и он еще не будет подписан, поэтому он также не получит обновление через канал.

Чтобы решить эту проблему, я думаю, мне нужен способ атомарного чтения текущего состояния, а затем подписки на pubsub, гарантирующий, что никакие сообщения не будут записаны в таблицу ETS или канал за этот период времени. Я думаю, замок? Это Эликсирей или есть другой способ?


person Amedee d'Aboville    schedule 20.06.2017    source источник


Ответы (1)


При написании этого вопроса я просмотрел ElixirConf Криса МакКорда. Учебные материалы 2015 г.. Я думал, что в этом примере было такое же состояние гонки, но оказалось, что это не так! Этот канал содержит решение.

В этом примере в функции Channel.join процесс отправляет себе сообщение :after_join, которое позже (после подписки) инициирует handle_info({:after_join...}) для чтения состояния приложения и отправки что пользователю.

Ключевым моментом является запрос состояния приложения после подписки.

А также всегда меняйте состояние перед публикацией.

Я говорю всегда, потому что я перебрал каждый из 24 возможных вариантов:

  • чтение состояния,
  • мутация состояния,
  • подписка на канал
  • публикация на канале

и подтвержденное чтение состояния после подписки в сочетании с обновлением состояния перед публикацией гарантировало отсутствие потери данных. Кратко о моей работе.

Это приводит к 4 возможным состояниям, когда изменение состояния наблюдается дважды, но с этим намного проще справиться, чем с потерей данных.

person Amedee d'Aboville    schedule 20.06.2017