Hi,
I am working on an application that mainly handles real-time data and user interaction. We have used live_view for it and are currently migrated to the latest live_view 20.0.
With the new live_view, I am delighted to have out-of-the-box solutions like assign_async, start_async, or stream. These new functions made our code base clean and elegant.
However, I have one very frequent case where we have to check our database periodically at intervals for some data updates and change our view accordingly after live_view mounts. So, it doesn’t make sense to make a dedicated Genserver for this case and publish messages when data changes.
For example, some other application is inserting some rules in the database. And based on that rule, my live_view needs to be updated. As insertion is done from another app, I cannot receive that update with Phoenix.PubSub and I also do not want to use any external PubSub for this case.
So, currently, we do something like the following.
def mount(_, session, socket) do
timer_ref = Process.send_after(self(), :check_changes, 2000)
socket =
socket
|> assign(:timer, timer_ref)
{:ok, socket}
end
def handle_info(:check_changes, socket) do
# check timer_ref, and clearout from assigns, if there,
Process.cancel_timer(socket.assigns.timer_ref)
# code related to checking
Process.send_after(self(), :check_changes, 2000)
{:noreply, socket}
end
It works kinda well if the check_changes handle doesn’t take too much time to process…otherwise, UI becomes laggy as the live_view process handles large operations.
So, I am thinking of some functions that can run parallelly with the live_view process at an interval and send updates to live_view, and live_view can handle that with handle_async
as it does it for the start_async
function.
Do you have any thoughts or better ideas, or does this kind of solution already exist? if not then I will implement this myself with the same logical pattern as start_async
.