GenServer state inspector
Mix . install ( [
{ :kino , "~> 0.12.3" }
] )
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
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 )