Skip to content

Instantly share code, notes, and snippets.

@hugobarauna
Last active March 25, 2024 16:59
Show Gist options
  • Save hugobarauna/d7a5fb5d3ca23c495e8d793acbfd51e7 to your computer and use it in GitHub Desktop.
Save hugobarauna/d7a5fb5d3ca23c495e8d793acbfd51e7 to your computer and use it in GitHub Desktop.
GenServer state inspector with Livebook

GenServer state inspector

Mix.install([
  {:kino, "~> 0.12.3"}
])

Section

defmodule GenServerInspector do
  use GenServer

  def start_link(state) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  @impl true
  def init(state) do
    schedule_work()

    {:ok, state}
  end

  @impl true
  def handle_info(:work, state) do
    genserver_state = :sys.get_state(state.pid)
    message = "State of GenServer #{:erlang.pid_to_list(state.pid)}: #{genserver_state}"
    Kino.Frame.render(state.frame, message)

    schedule_work()

    {:noreply, state}
  end

  defp schedule_work do
    Process.send_after(self(), :work, :timer.seconds(1))
  end
end
import Kino.Shorts
pid = read_text("PID")

if pid == "" do
  Kino.interrupt!(:normal, "need to fill in PID")
else
  pid = :erlang.list_to_pid(~c"<#{pid}>")
  Process.alive?(pid)
end
if inspector_pid = Process.whereis(GenServerInspector), do: GenServer.stop(inspector_pid)

pid = :erlang.list_to_pid(~c"<#{pid}>")
frame = Kino.Frame.new()
{:ok, _} = GenServerInspector.start_link(%{pid: pid, frame: frame})
frame
if inspector_pid = Process.whereis(GenServerInspector), do: GenServer.stop(inspector_pid)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment