Skip to content

Instantly share code, notes, and snippets.

@fishcakez
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fishcakez/bd2be0f2174a091acda1 to your computer and use it in GitHub Desktop.
Save fishcakez/bd2be0f2174a091acda1 to your computer and use it in GitHub Desktop.
EnterLoop
defmodule EnterLoop do
use GenServer
require Logger
def start_link(opts) do
spawn_opts = Keyword.get(opts, :spawn_opt, [])
# :infinity start timeout
:proc_lib.start_link(__MODULE__, :init_it, [opts], :infinity, spawn_opts)
end
def init_it(opts) do
register()
try do
# do some init
:ok
# send ackowledgement to starter
:proc_lib.init_ack({:ok, self()})
else
:ok ->
# do more init
post_ack()
catch
# include stacktrace in exit reason on error
:error, value ->
init_stop({value, System.stacktrace()})
:throw, value ->
init_stop({{:nocatch, value}, System.stacktrace()})
:exit, value ->
init_stop(value)
end
end
defp register() do
try do
Process.register(self(), __MODULE__)
rescue
ArgumentError ->
pid = Process.whereis(__MODULE__) || :undefined
reason = {:error, {:already_started, pid}}
:proc_lib.init_ack(reason)
exit(:normal)
end
end
defp post_ack() do
try do
# do more init
:ok
else
:ok ->
# nil state, :infinity timeout.
:gen_server.enter_loop(__MODULE__, opts, nil, {:local, __MODULE__},
:infinity)
catch
# include stacktrace in exit reason on error
:error, value ->
stop({value, System.stacktrace()})
:throw, value ->
stop({{:nocatch, value}, System.stacktrace()})
:exit, value ->
stop(value)
end
end
defp init_stop(reason) do
# no need to log here because reason passed to starter
# unregister first before sending ack so that not still registered if
# supervisor tries again. This may only be required for :global or :via
Process.unregister(__MODULE__)
# send error acknowledgement
:proc_lib.init_ack({:error, reason})
exit(reason)
end
defp stop(reason) do
# might want to log error
Logger.error("Failed to init #{__MODULE__}\n" <>
Exception.format_exit(reason))
exit(reason)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment