daveboo
LiveView callbacks firing on websocket heartbeat
Possibly related to Liveview form keeps on refreshing every 15s , but my problem is slightly different IMO.
I have a callback (“status”) that should only be firing when the value is changed in the select box on the form. Unfortunately, it is firing when the form is idle and the liveview heartbeat happens. This problem is compounded by the fact that it sends out a notification and spams the mobile user’s app.
I’ve provided the select and callback code blocks below:
<td class="td">
<div class="flex-container <%= get_status_class(row) %>">
<div class="dropdown-wrapper">
<%= f = form_for :f, "#", [class: "form form-group", phx_change: :status] %>
<%= hidden_input f, :sub_id, value: row.subscription_id %>
<%= hidden_input f, :user_id, value: row.user_id %>
<%= hidden_input f, :dep_id, value: row.dependent_id %>
<%= case row do %>
<% %{connection: :inactive} -> %>
<%= select f, :status, @paused_statuses, selected: row.connection, disabled: true, class: "flex-item MR15 dropdown js-status-dropdown", id: "status-#{row.subscription_id}-#{row.id}" %>
<% _ -> %>
<%= select f, :status, @connection_statuses, selected: row.connection, class: "flex-item MR15 dropdown js-status-dropdown", id: "status-#{row.subscription_id}-#{row.id}" %>
<% end %>
</form>
</div>
</div>
</td>
@impl true
def handle_event(
"status",
%{"f" => %{"status" => status, "sub_id" => id, "user_id" => user_id, "dep_id" => ""}},
socket
) do
_ =
Logger.info(
"#{__MODULE__}: event: status: #{inspect(status)}. sub_id: #{inspect(id)}, user_id: #{
inspect(user_id)
}"
)
status = String.to_atom(status)
case Connection.update_status(id, status) do
:error ->
_ =
Logger.info(
"#{__MODULE__}: event: Failed to update: #{inspect(status)}. sub_id: #{inspect(id)}, user_id: #{
inspect(user_id)
}"
)
{:noreply, socket}
:ok ->
# Update the assign data with the new status value to update the view
{:noreply, assign(socket, data: update_view_status(socket.assigns.data, user_id, status))}
end
end
Any thoughts?
Most Liked
Nicd
Unrelated to the issue itself, but this is dangerous. A user can use this to exhaust your atom table, leading to crash of the VM. You should manually convert allowed values to atoms or use String.to_existing_atom/1 that doesn’t allow creation of new atoms.
Nicd
Yes, the atom table has a fixed upper size limit. If you try to create more atoms, the VM crashes. For example:
iex(1)> for i <- 1..1000000000, do: String.to_atom("test-#{i}")
no more index entries in atom_tab (max=1048576)
Crash dump is being written to: erl_crash.dump...done
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









