Skip to content

Commit

Permalink
Disable Connection.Controller before shutdown
Browse files Browse the repository at this point in the history
Stopping it  had its supervisor restart it just before actual shutdown
  • Loading branch information
jfcloutier committed Apr 4, 2022
1 parent fda1428 commit b20dbe9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
41 changes: 31 additions & 10 deletions lib/tortoise311/connection/controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ defmodule Tortoise311.Connection.Controller do
Tortoise311.Registry.via_name(__MODULE__, client_id)
end

# This is sent just before the Controller's supervisor is shutdown.
# All we want to do here is disable the controller until it is terminated by its supervisor shutting down.
def stop(client_id) do
GenServer.stop(via_name(client_id))
GenServer.cast(via_name(client_id), :stop)
end

def info(client_id) do
Expand Down Expand Up @@ -123,6 +125,11 @@ defmodule Tortoise311.Connection.Controller do
end

@impl GenServer

def handle_cast(_, %State{status: :stopped} = state), do: {:noreply, state}

def handle_cast(:stop, state), do: {:noreply, %State{state | status: :stopped}}

def handle_cast({:incoming, <<package::binary>>}, state) do
package
|> Package.decode()
Expand Down Expand Up @@ -152,19 +159,27 @@ defmodule Tortoise311.Connection.Controller do
{:result, {Package.Subscribe, subacks}},
%State{handler: handler} = state
) do
case Handler.execute(handler, {:subscribe, subacks}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
if state.status != :stopped do
case Handler.execute(handler, {:subscribe, subacks}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
end
else
{:noreply, state}
end
end

def handle_cast(
{:result, {Package.Unsubscribe, unsubacks}},
%State{handler: handler} = state
) do
case Handler.execute(handler, {:unsubscribe, unsubacks}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
if state.status != :stopped do
case Handler.execute(handler, {:unsubscribe, unsubacks}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
end
else
{:noreply, state}
end
end

Expand All @@ -175,13 +190,19 @@ defmodule Tortoise311.Connection.Controller do
{:onward, %Package.Publish{qos: 2, dup: false} = publish},
%State{handler: handler} = state
) do
case Handler.execute(handler, {:publish, publish}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
if state.status != :stopped do
case Handler.execute(handler, {:publish, publish}) do
{:ok, updated_handler} ->
{:noreply, %State{state | handler: updated_handler}}
end
else
{:noreply, state}
end
end

@impl GenServer
def handle_info(_, %State{status: :stopped} = state), do: {:noreply, state}

def handle_info({:next_action, {:subscribe, topic, opts} = action}, state) do
{qos, opts} = Keyword.pop_first(opts, :qos, 0)

Expand Down
4 changes: 2 additions & 2 deletions test/tortoise/connection/controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ defmodule Tortoise311.Connection.ControllerTest do
assert {:ok, pid} = Controller.start_link(opts)
assert Process.alive?(pid)
assert :ok = Controller.stop(context.client_id)
refute Process.alive?(pid)
assert_receive {:terminating, :normal}
state = Controller.info(context.client_id)
assert state.status == :stopped
end

describe "Connection callback" do
Expand Down

0 comments on commit b20dbe9

Please sign in to comment.