Current section

Files

Jump to
wallaby lib wallaby session_store.ex
Raw

lib/wallaby/session_store.ex

defmodule Wallaby.SessionStore do
@moduledoc false
use GenServer
use EventEmitter, :emitter
alias Wallaby.WebdriverClient
def start_link(opts \\ []) do
{opts, args} = Keyword.split(opts, [:name])
GenServer.start_link(__MODULE__, args, opts)
end
def monitor(store \\ __MODULE__, session) do
GenServer.call(store, {:monitor, session}, 10_000)
end
def demonitor(store \\ __MODULE__, session) do
GenServer.call(store, {:demonitor, session})
end
def list_sessions_for(opts \\ []) do
name = Keyword.get(opts, :name, :session_store)
owner_pid = Keyword.get(opts, :owner_pid, self())
:ets.select(name, [{{{:_, :_, :"$1"}, :"$2"}, [{:==, :"$1", owner_pid}], [:"$2"]}])
end
def init(args) do
name = Keyword.get(args, :ets_name, :session_store)
opts =
if(name == :session_store, do: [:named_table], else: []) ++
[:set, :public, read_concurrency: true]
Process.flag(:trap_exit, true)
tid = :ets.new(name, opts)
Application.ensure_all_started(:ex_unit)
ExUnit.after_suite(fn _ ->
try do
:ets.tab2list(tid)
|> Enum.each(&delete_sessions/1)
rescue
_ -> nil
end
end)
{:ok, %{ets_table: tid}}
end
def handle_call({:monitor, session}, {pid, _ref}, state) do
ref = Process.monitor(pid)
:ets.insert(state.ets_table, {{ref, session.id, pid}, session})
emit(%{module: __MODULE__, name: :monitor, metadata: %{monitored_session: session}})
{:reply, :ok, state}
end
def handle_call({:demonitor, session}, _from, state) do
result =
:ets.select(state.ets_table, [
{{{:"$1", :"$2", :"$3"}, :_}, [{:==, :"$2", session.id}], [{{:"$1", :"$3"}}]}
])
case result do
[{ref, pid}] ->
true = Process.demonitor(ref)
:ets.delete(state.ets_table, {ref, session.id, pid})
[] ->
:ok
end
{:reply, :ok, state}
end
def handle_info({:DOWN, ref, :process, pid, _reason}, state) do
[session] =
:ets.select(state.ets_table, [
{{{:"$1", :_, :_}, :"$4"}, [{:==, :"$1", ref}], [:"$4"]}
])
WebdriverClient.delete_session(session)
:ets.delete(state.ets_table, {ref, session.id, pid})
emit(%{module: __MODULE__, name: :DOWN, metadata: %{monitored_session: session}})
{:noreply, state}
end
defp delete_sessions({_, session}) do
WebdriverClient.delete_session(session)
end
end