Current section

Files

Jump to
live_debugger lib live_debugger app web hooks tracer_status.ex
Raw

lib/live_debugger/app/web/hooks/tracer_status.ex

defmodule LiveDebugger.App.Web.Hooks.TracerStatus do
@moduledoc """
This hook manages the tracing status and handles the case when the tracer crashes.
It listens for `DbgKilled` and `DbgStarted` events and updates the `:tracer_started?` assign accordingly.
### Important
It requires subscribing to events `Bus.receive_events!()` in LiveView.
"""
use LiveDebugger.App.Web, :hook
alias LiveDebugger.Services.CallbackTracer.GenServers.TracingManager
alias Phoenix.LiveView.AsyncResult
alias LiveDebugger.Services.CallbackTracer.Events.DbgKilled
alias LiveDebugger.Services.CallbackTracer.Events.DbgStarted
require Logger
@tracer_state_request_timeout 3000
@spec init(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
def init(socket) do
socket
|> attach_hook(:tracer_status, :handle_info, &handle_info/2)
|> attach_hook(:tracer_status, :handle_async, &handle_async/3)
|> register_hook(:tracer_status)
|> assign(:tracer_started?, AsyncResult.loading())
|> start_async(:tracer_started?, fn -> tracer_status() end)
end
defp handle_info(%DbgKilled{}, socket) do
socket
|> assign(:tracer_started?, AsyncResult.ok(false))
|> push_event("clear_dismissed", %{})
|> halt()
end
defp handle_info(%DbgStarted{}, socket) do
{:halt, assign(socket, :tracer_started?, AsyncResult.ok(true))}
end
defp handle_info(_, socket), do: {:cont, socket}
defp handle_async(:tracer_started?, {:ok, started?}, socket) do
{:halt, assign(socket, :tracer_started?, AsyncResult.ok(started?))}
end
defp handle_async(:tracer_started?, _, socket) do
{:halt, assign(socket, :tracer_started?, AsyncResult.ok(false))}
end
defp handle_async(_, _, socket), do: {:cont, socket}
defp tracer_status() do
%{:dbg_pid => dbg_pid} =
GenServer.call(TracingManager, :get_state, @tracer_state_request_timeout)
dbg_pid != nil
end
end