summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/exirc/client.ex13
-rw-r--r--lib/exirc/exirc.ex2
-rw-r--r--test/client_test.exs25
3 files changed, 34 insertions, 6 deletions
diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex
index cde4f1a..81a2f0a 100644
--- a/lib/exirc/client.ex
+++ b/lib/exirc/client.ex
@@ -32,7 +32,8 @@ defmodule ExIrc.Client do
channels: [],
debug?: false,
retries: 0,
- inet: :inet
+ inet: :inet,
+ owner: nil
end
#################
@@ -55,6 +56,7 @@ defmodule ExIrc.Client do
"""
@spec start_link(options :: list() | nil, process_opts :: list() | nil) :: {:ok, pid} | {:error, term}
def start_link(options \\ [], process_opts \\ []) do
+ options = Keyword.put_new(options, :owner, self())
GenServer.start_link(__MODULE__, options, process_opts)
end
@doc """
@@ -285,17 +287,20 @@ defmodule ExIrc.Client do
def init(options \\ []) do
autoping = Keyword.get(options, :autoping, true)
debug = Keyword.get(options, :debug, false)
+ owner = Keyword.fetch!(options, :owner)
# Add event handlers
handlers =
Keyword.get(options, :event_handlers, [])
|> List.foldl([], &do_add_handler/2)
+ ref = Process.monitor(owner)
# Return initial state
{:ok, %ClientState{
event_handlers: handlers,
autoping: autoping,
logged_on?: false,
debug?: debug,
- channels: ExIrc.Channels.init()}}
+ channels: ExIrc.Channels.init(),
+ owner: {owner, ref}}}
end
@doc """
Handle calls from the external API. It is not recommended to call these directly.
@@ -497,6 +502,10 @@ defmodule ExIrc.Client do
def handle_info({:ssl, socket, data}, state) do
handle_info({:tcp, socket, data}, state)
end
+ # If the owner process dies, we should die as well
+ def handle_info({:DOWN, ref, _, pid, reason}, %{owner: {pid, ref}} = state) do
+ {:stop, reason, state}
+ end
# If an event handler process dies, remove it from the list of event handlers
def handle_info({:DOWN, _, _, pid, _}, state) do
handlers = do_remove_handler(pid, state.event_handlers)
diff --git a/lib/exirc/exirc.ex b/lib/exirc/exirc.ex
index cfa2654..72be33c 100644
--- a/lib/exirc/exirc.ex
+++ b/lib/exirc/exirc.ex
@@ -50,7 +50,7 @@ defmodule ExIrc do
@spec start_client! :: {:ok, pid} | {:error, term}
def start_client! do
# Start the client worker
- Supervisor.start_child(:exirc, [])
+ Supervisor.start_child(:exirc, [[owner: self()]])
end
##############
diff --git a/test/client_test.exs b/test/client_test.exs
index 6cff0b7..b7277b6 100644
--- a/test/client_test.exs
+++ b/test/client_test.exs
@@ -1,11 +1,30 @@
defmodule ExIrc.ClientTest do
use ExUnit.Case
-
test "start multiple clients" do
- {:ok, pid} = ExIrc.start_client!
- {:ok, pid2} = ExIrc.start_client!
+ assert {:ok, pid} = ExIrc.start_client!
+ assert {:ok, pid2} = ExIrc.start_client!
assert pid != pid2
end
+ test "client dies if owner process dies" do
+ test_pid = self()
+
+ pid = spawn_link(fn ->
+ assert {:ok, pid} = ExIrc.start_client!
+ send(test_pid, {:client, pid})
+ receive do
+ :stop -> :ok
+ end
+ end)
+
+ client_pid = receive do
+ {:client, pid} -> pid
+ end
+
+ assert Process.alive?(client_pid)
+ send(pid, :stop)
+ :timer.sleep(1)
+ refute Process.alive?(client_pid)
+ end
end