I am building a market scanner as a practice app and require a message to be sent to the client every 5 seconds with results from the scanner. I have chosen to do this over channels but have hit a snag. I am unsure with which is the best way to continuously send these messages. The recursive loop I created continues inevitably (until client disconnects) but therefore never returns the socket to Phoenix limiting my ability to manipulate it for other changes (ie: setting changes, etc…). See below for code:
defmodule MyApp.ScannerChannel do
def join...
def handle_in("alert", _args, socket) do
IO.puts("Starting Alert Loop...")
alert_loop(socket)
{:noreply, socket}
end
def alert_loop(%{assigns: %{user_pid: user_pid}} = socket) do
response_map =
MyApp.delta_alert?(socket.assigns[:user_pid])
|> build_trades_map(%{})
|> alert_checker(socket)
updated_socket = assign(socket, :trades_map, response_map)
push(updated_socket, "alert", response_map)
Process.sleep(5_000)
alert_loop(updated_socket)
end
def alert_loop(_socket_no_user_pid), do: nil
This approach limits me significantly and won’t work once I require more interaction with my socket.
Some other options I have thought of are as follows:
-
Send a message from the client requesting the data every 5 seconds. Issue: For multiple reasons, I would prefer to do it on the backend totally if possible. This is my last resort.
-
Process.send_after - Request the data through a delayed message. Issue: Same as my current solution. The socket would be continuously passed back and forth and therefore not be updated.
-
Broadcast/3 - Could just loop a broadcast. Issue: Each user has individual scanner settings and so this wouldn’t work as it would just send out results calculated using default settings.
Does anyone have any other ideas for how I could send a message repeatedly on a set interval?
Thanks.