Current section
Files
Jump to
Current section
Files
lib/live_debugger_web/live/traces/hooks/existing_traces.ex
defmodule LiveDebuggerWeb.Live.Traces.Hooks.ExistingTraces do
@moduledoc """
This hook is responsible for fetching the existing traces.
It is used to fetch the existing traces when the user clicks the "Load more" button
"""
use LiveDebuggerWeb, :hook
require Logger
alias LiveDebugger.Structs.TraceDisplay
alias LiveDebugger.Services.TraceService
# These functions are using the `current_filters` assigns
import LiveDebuggerWeb.Live.Traces.Helpers,
only: [get_active_functions: 1, get_execution_times: 1]
@required_assigns [
:lv_process,
:current_filters,
:traces_empty?,
:traces_continuation,
:existing_traces_status
]
@doc """
Initializes the hook by attaching the hook to the socket and checking the required assigns.
"""
@spec init(Phoenix.LiveView.Socket.t(), integer()) :: Phoenix.LiveView.Socket.t()
def init(socket, page_size \\ 25) do
socket
|> check_hook!(:tracing_fuse)
|> check_assigns!(@required_assigns)
|> check_stream!(:existing_traces)
|> put_private(:page_size, page_size)
|> attach_hook(:existing_traces, :handle_async, &handle_async/3)
|> register_hook(:existing_traces)
|> assign_async_existing_traces()
end
@doc """
Loads the existing traces asynchronously and assigns them to the socket.
"""
@spec assign_async_existing_traces(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
def assign_async_existing_traces(socket) do
pid = socket.assigns.lv_process.pid
node_id = Map.get(socket.assigns, :node_id)
active_functions = get_active_functions(socket)
execution_times = get_execution_times(socket)
page_size = socket.private.page_size
opts =
[
limit: page_size,
functions: active_functions,
execution_times: execution_times,
node_id: node_id
]
socket
|> assign(:existing_traces_status, :loading)
|> stream(:existing_traces, [], reset: true)
|> start_async(:fetch_existing_traces, fn ->
TraceService.existing_traces(pid, opts)
end)
end
defp handle_async(:fetch_existing_traces, {:ok, {trace_list, cont}}, socket) do
trace_list = Enum.map(trace_list, &TraceDisplay.from_trace/1)
socket
|> assign(existing_traces_status: :ok)
|> assign(:traces_empty?, false)
|> assign(:traces_continuation, cont)
|> stream(:existing_traces, trace_list)
|> halt()
end
defp handle_async(:fetch_existing_traces, {:ok, :end_of_table}, socket) do
socket
|> assign(existing_traces_status: :ok)
|> assign(traces_continuation: :end_of_table)
|> halt()
end
defp handle_async(:fetch_existing_traces, {:exit, reason}, socket) do
Logger.error(
"LiveDebugger encountered unexpected error while fetching existing traces: #{inspect(reason)}"
)
socket
|> assign(existing_traces_status: :error)
|> halt()
end
defp handle_async(_, _, socket), do: {:cont, socket}
end