-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0a66caa
commit bc434ad
Showing
9 changed files
with
262 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
defmodule Cocktailparty.SinkCatalog.RedisChannelSink do | ||
use Cocktailparty.SinkCatalog.SinkBehaviour | ||
use GenServer | ||
|
||
require Logger | ||
|
||
alias Redix | ||
|
||
## Required Fields | ||
|
||
@impl Cocktailparty.SinkCatalog.SinkBehaviour | ||
def required_fields do | ||
[:channel] | ||
end | ||
|
||
## Public API | ||
@impl Cocktailparty.SinkCatalog.SinkBehaviour | ||
def publish(pid, message) do | ||
GenServer.call(pid, {:publish, message}) | ||
end | ||
|
||
## GenServer Callbacks | ||
def start_link(%Cocktailparty.SinkCatalog.Sink{} = sink) do | ||
GenServer.start_link(__MODULE__, sink, name: {:global, {:sink, sink.id}}) | ||
end | ||
|
||
@impl GenServer | ||
def init(sink) do | ||
# We just check whether the connection process exists | ||
with conn_pid <- :global.whereis_name({"redis_pub", sink.connection_id}) do | ||
# Subscribe to the Redis channel | ||
{:ok, | ||
%{ | ||
conn_pid: conn_pid, | ||
channel: sink.config["channel"], | ||
source_id: sink.id | ||
}} | ||
else | ||
:undefined -> {:stop, {:connection_not_found, sink.connection_id}} | ||
end | ||
end | ||
|
||
#TODO | ||
|
||
@impl GenServer | ||
def handle_call({:publish, message}, _from, %{redix_conn: redix_conn, channel: channel} = state) do | ||
case Redix.command(redix_conn, ["PUBLISH", channel, message]) do | ||
{:ok, _count} -> | ||
{:reply, :ok, state} | ||
{:error, reason} -> | ||
{:reply, {:error, reason}, state} | ||
end | ||
end | ||
|
||
@impl GenServer | ||
def terminate(_reason, %{redix_conn: redix_conn}) do | ||
if Process.alive?(redix_conn) do | ||
Redix.stop(redix_conn) | ||
end | ||
:ok | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
defmodule Cocktailparty.SinkCatalog.SinkBehaviour do | ||
@moduledoc """ | ||
Defines the behavior that all sink modules must implement. | ||
""" | ||
|
||
@callback required_fields() :: [atom()] | ||
@doc""" | ||
Takes a sink process PID and a message (of any type) and returns :ok or an error tuple. | ||
""" | ||
@callback publish(pid(), term()) :: :ok | {:error, term()} | ||
|
||
defmacro __using__(_) do | ||
quote do | ||
@behaviour Cocktailparty.SinkCatalog.SinkBehaviour | ||
|
||
def required_fields, do: [] | ||
|
||
defoverridable required_fields: 0 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
defmodule Cocktailparty.SinkCatalog.SinkType do | ||
@moduledoc """ | ||
Defines the available sink types for each connection type. | ||
""" | ||
|
||
@sink_types %{ | ||
"redis_pub" => [ | ||
%{type: "pub", module: Cocktailparty.SinkCatalog.RedisChannel, required_fields: [:channel]} | ||
] | ||
} | ||
|
||
@doc """ | ||
Returns the list of source types available for the given connection type. | ||
""" | ||
def get_sink_types_for_connection(connection_type) do | ||
Map.get(@sink_types, connection_type, []) | ||
end | ||
|
||
@doc """ | ||
Returns the module associated with the given connection type and source type. | ||
""" | ||
def get_module(connection_type, sink_type) do | ||
@sink_types | ||
|> Map.get(connection_type, []) | ||
|> Enum.find(fn %{type: type} -> type == sink_type end) | ||
|> case do | ||
%{module: module} -> {:ok, module} | ||
nil -> {:error, :unknown_source_type} | ||
end | ||
end | ||
|
||
@doc """ | ||
Returns the required fields for the given connection type and source type. | ||
""" | ||
def get_required_fields(connection_type, sink_type) do | ||
@sink_types | ||
|> Map.get(connection_type, []) | ||
|> Enum.find(fn %{type: type} -> type == sink_type end) | ||
|> case do | ||
%{required_fields: fields} -> {:ok, fields} | ||
_ -> {:error, :unknown_source_type} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters