Skip to content

Commit

Permalink
introduce the Gnat.Supervisor macro
Browse files Browse the repository at this point in the history
  • Loading branch information
mmmries committed Oct 19, 2024
1 parent 43ba8d4 commit 23565db
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
8 changes: 8 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Config

if Mix.env() == :test do
config :gnat, Gnat.SupervisorTest.MyApp.Gnat,
connection_settings: [
%{}
]
end
4 changes: 2 additions & 2 deletions lib/gnat/connection_supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ defmodule Gnat.ConnectionSupervisor do
name: :gnat, # (required) the registered named you want to give the Gnat connection
backoff_period: 4_000, # number of milliseconds to wait between consecutive reconnect attempts (default: 2_000)
connection_settings: [
%{host: '10.0.0.100', port: 4222},
%{host: '10.0.0.101', port: 4222},
%{host: ~c"10.0.0.100", port: 4222},
%{host: ~c"10.0.0.101", port: 4222},
]
}
```
Expand Down
72 changes: 72 additions & 0 deletions lib/gnat/supervisor.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
defmodule Gnat.Supervisor do
defmacro __using__(opts) do
quote do
@mod __MODULE__

use Supervisor

def start_link(init_arg) do
Supervisor.start_link(__MODULE__, init_arg)
end

@impl true
def init(_init_arg) do
otp_app = unquote(opts)[:otp_app] || raise ArgumentError, "otp_app option is required"
config = Application.get_env(otp_app, @mod, [])

children = [
{Gnat.ConnectionSupervisor, connection_opts(config)},
consumer_supervisor(config)
]
|> List.flatten()

Supervisor.init(children, strategy: :one_for_one)
end

defp connection_opts(config) do
%{
name: @mod,
connection_settings: Keyword.get(config, :connection_settings)
}
end

defp consumer_supervisor(config) do
case Keyword.get(config, :topics) do
nil -> []
topics when is_list(topics) -> [{Gnat.ConsumerSupervisor, topics}]
_ -> raise ArgumentError, "Invalid :topics option. Expected a list of topics."
end
end

## Functions that forward to Gnat connection

def active_subscriptions() do
Gnat.active_subscriptions(@mod)
end

def pub(topic, message, opts \\ []) do
Gnat.pub(@mod, topic, message, opts)
end

def request(topic, body, opts \\ []) do
Gnat.request(@mod, topic, body, opts)
end

def request_multi(topic, body, opts \\ []) do
Gnat.request_multi(@mod, topic, body, opts)
end

def server_info() do
Gnat.server_info(@mod)
end

def sub(subscriber, topic, opts \\ []) do
Gnat.sub(@mod, subscriber, topic, opts)
end

def unsub(sid, opts \\ []) do
Gnat.unsub(@mod, sid, opts)
end
end
end
end
24 changes: 24 additions & 0 deletions test/gnat/supervisor_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Gnat.SupervisorTest do
use ExUnit.Case, async: true

defmodule MyApp.Gnat do
use Gnat.Supervisor, otp_app: :gnat
end

test "it can be supervised" do
assert MyApp.Gnat.child_spec([]) == %{
id: MyApp.Gnat,
start: {MyApp.Gnat, :start_link, [[]]},
type: :supervisor
}
end

test "when started - it provides an API that does not require a Gnat connection arg" do
{:ok, _pid} = MyApp.Gnat.start_link([])
:timer.sleep(100)
{:ok, _sub} = MyApp.Gnat.sub(self(), "my_app.topic")
:ok = MyApp.Gnat.pub("my_app.topic", "ohai")
assert_receive {:msg, %{topic: "my_app.topic", body: "ohai"}}
assert Supervisor.stop(MyApp.Gnat) == :ok
end
end

0 comments on commit 23565db

Please sign in to comment.