affq19

affq19

ChatRoom in Elixir using Mutex and Threads

Hi! I’ve been studying concurrency models with elixir. Now, I want to develop a ChatRoom, where users can Join, post messages, and disconnect themselves using threads and mutex in elixir. So far I have developed the model for entering new users and disconnect them. However, I have put some “prints” to see how its working, but they are not showing when I run the program. This is the code,

defmodule MyMutex do
  @mutex :free

  def lock(:free) do
    {:ok, :locked}
  end

  def lock(:locked) do
    {:error, :already_locked}
  end

  def unlock(:locked) do
    :ok
  end

  def unlock(:free) do
    {:error, :not_locked}
  end
end

defmodule Chat do

  defstruct users: [], messages: [], mutex: MyMutex

  def start_link() do
    {:ok, pid} = Task.start_link(fn -> action(%__MODULE__{}) end)
  end

  defp action(chat) do
    receive do
    {:join, :user} ->
      chat = new_user(chat, :user)
      action(chat)
    #{:post, user} ->
    #  chat = post_message(chat, user)
    #  action(chat)
    {:disconnect, user} ->
      chat = disconnect_user(chat, user)
      action(chat)
    {:users_chat} ->
      post_all_users(chat)
      action(chat)
    end
  end

  defp post_all_users(chat) do
    Enum.each(chat.users, fn user ->
      "User:"
    end)
  end

  defp post_message_to_all(chat, message) do
    Enum.each(chat.users, fn user ->
      IO.puts("Message from server: #{message} (Sent to: #{user})")
    end)
  end

  defp new_user(chat ,user) do
    {:ok, mutex} = MyMutex.lock(chat.mutex)
    updated_chat = %{ chat | users: chat.users ++ [user], mutex: mutex }
    IO.puts("Entering the chat: #{user}")
    MyMutex.unlock(mutex)
    post_message_to_all(updated_chat, "#{user} has joined the chat.")
    updated_chat
  end

  defp disconnect_user(chat, user) do
    {:ok, mutex} = MyMutex.lock(chat.mutex)
    chat = %{chat | users: List.delete(chat.users, user),
            mutex: mutex}
    IO.puts("The user #{user} has leaved the chat")
    MyMutex.lock(mutex)
    chat
  end

end

Thanks in Advice :slight_smile:

Most Liked

dimitarvp

dimitarvp

What was your education source that claimed you need mutexes in Elixir? :thinking:

You don’t need them here.

kokolegorille

kokolegorille

Hello and welcome,

Do You really need mutex in Elixir?

You might be interested by this YT video

by @geo

arijoon

arijoon

I have to agree with other posters regarding mutex. General usecase for a mutex is to lock a shared resource when multiple threads are writing to it. In erlang we have processes which do not share resources. If you wish to share something (for example the chat messages), you can create a new process which holds this information and read/write to it by sending messages to that process. Since the process will only action one message at a time, no mutex will be required

Last Post!

geo

geo

Author of Phoenix in Action

:wave: I was brought here by the mention of @kokolegorille. It looks like you’ve received some great direction here already!

However, I wouldn’t be a good marketer if I didn’t mention that I have a course that goes into detail building a chat room system from scratch using LiveView. And initially we do it without a database—building a GenServer to handle messages in-memory as a stepping stone.

Anyway, if you’re interested, check out https://BuildItWithPhoenix.com.

Where Next?

Popular in Questions Top

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New

Other popular topics Top

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement