Sqllitex.Server has stop/1
Consider this standin:
# file: my_app/lib/server.ex
#
defmodule Server do
use GenServer
def start_link(args),
do: GenServer.start_link(__MODULE__, args)
def init(args),
do: {:ok, args}
def handle_cast(:stop, state) do
{:stop, :normal, state}
end
def terminate(reason, state) do
IO.puts("#{__MODULE__} terminate - reason: #{inspect(reason)} state: #{inspect(state, pretty: true)}")
:ok
end
# ---
def stop(pid),
do: GenServer.cast(pid, :stop)
end
and this application:
# file: my_app/lib/my_app/application.ex
#
# created with "mix new my_app --sup"
#
defmodule MyApp.Application do
use Application
# @server_timeout 30 * 60 * 1000
@server_timeout 30_000
@supervisor_name MyApp.Supervisor
def start(_type, _args) do
children = [
Supervisor.child_spec({Server, [:config, :server]}, restart: :transient)
]
# restart: transient
# otherwise supervisor will restart Server process
opts = [strategy: :one_for_one, name: @supervisor_name]
case Supervisor.start_link(children, opts) do
{:ok, _} = on_start ->
Task.start(__MODULE__, :timeout_server, [])
on_start
on_start ->
on_start
end
end
def timeout_server() do
with {:ok, server_pid} <- find_server() do
# Terminate this task if server terminates (and vice versa)
Process.link(server_pid)
# Now wait
Process.sleep(@server_timeout)
# Let server terminate normally
Process.unlink(server_pid)
# Initiate server termination
Server.stop(server_pid)
end
end
def find_server() do
case Enum.find(Supervisor.which_children(@supervisor_name), &server_module?/1) do
{_, server_pid, _, _} when is_pid(server_pid) ->
{:ok, server_pid}
_ ->
{:error, :not_found}
end
end
defp server_module?({_, _, _, [Server | _]}),
do: true
defp server_module?(_),
do: false
end
then
$ iex -S mix
Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Compiling 2 files (.ex)
Interactive Elixir (1.9.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> MyApp.Application.find_server()
{:ok, #PID<0.149.0>}
iex(2)> Elixir.Server terminate - reason: :normal state: [:config, :server]
iex(2)> MyApp.Application.find_server()
{:error, :not_found}
iex(3)>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
$