Извините за тупой вопрос. Но я новичок ie в эликсире, пришедший из golang.
Я действительно люблю стиль эликсира и FP, я пытаюсь реализовать некоторые базовые функции c и у меня возникли проблемы с условиями гонки при подключении через веб-сокет , Например, в golang я разрешил это с помощью Mutex, но это не стиль FP.
Первоначальная проблема: несколько соединений WebSocket, ожидающих группу из 5. И затем случайным образом перетасовывают людей. В этом случае у меня были некоторые проблемы с «состоянием гонки». Одинаковые люди в разных группах и т. Д. c.
Какой правильный идиоматический c способ решить эту проблему в эликсире?
Спасибо за вашу помощь. И еще раз прошу прощения за глупый вопрос.
Я поделюсь своим уродливым фрагментом кода)
Например, два одновременных пользователя присоединяются к лобби-каналу, который я отслеживаю, они присоединились через присутствие. После этого, когда некоторые пользователи отправляют событие «матч», я нахожу других онлайн-пользователей в лобби, пока их не станет больше.
defp match(user_id, online_list) when length(online_list) < 1
Затем я создаю комнату и отправляю им room_id. Но когда два пользователя отправляют совпадение, у меня две комнаты из-за состояния гонки.
Я хочу иметь одну общую комнату для группы пользователей. В lang такие go, я мог бы использовать mutex и делиться. Но я не знаю, как реализовать эту логику c в эликсире.
Прямо сейчас, если Алиса вызывает событие, и у меня достаточно пользователя для Алисы, но Боб вызывает это событие одновременно, и он также было достаточно пользователей. Но они должны быть в общей группе, а не в двух отдельных. Они пересекаются
def match(user_id) do
user_id = Integer.to_string(user_id)
match(user_id, [])
end
defp match(user_id, online_list) when length(online_list) < 1 do
new_online_list =
RchatWeb.Presence.list("room:lobby")
|> Map.delete(user_id)
|> Map.keys()
match(user_id, new_online_list)
end
defp match(first_user_id, online_list) do
second_user_id = Enum.random(online_list) |> String.to_integer()
second_room_id = Accounts.get_user_room_id(second_user_id)
{:ok, room} = cond do
is_nil(second_room_id) -> create_room()
true -> {:ok, get_room!(second_room_id)}
end
# Try to fix race condition with presence or channels
{:ok, first_user} =
Accounts.get_user!(first_user_id)
|> Accounts.update_user(%{room_id: room.id})
{:ok, second_user} =
Accounts.get_user!(second_user_id)
|> Accounts.update_user(%{room_id: room.id})
ids = [first_user.id, second_user.id]
{:ok, room.hash, ids}
end