Cleanup work
This commit is contained in:
parent
eb6631dd8b
commit
f0cf03141b
11 changed files with 59 additions and 9 deletions
|
|
@ -1,4 +1,18 @@
|
|||
defmodule BirdyChat.Dispatcher do
|
||||
@moduledoc """
|
||||
Main dispatcher of messages - decides to either write them to local file system or send them via
|
||||
HTTP to peers.
|
||||
|
||||
It originally started as a websocket connection between servers, but then I decided to rip
|
||||
it out and replace with simple HTTP request-response for the following reasons:
|
||||
|
||||
1. HTTP guarantees immediate feedback (request succeeds or not), making the addition of caching
|
||||
or retries easy.
|
||||
2. HTTP requests have well-know semantic so I can i.e use HTTP statuses for error signals
|
||||
instead of inventing my own error language.
|
||||
"""
|
||||
|
||||
@spec dispatch(Ecto.Changeset.t()) :: :ok | {:error, String.t()}
|
||||
def dispatch(%Ecto.Changeset{changes: changes} = changeset) do
|
||||
case changes do
|
||||
%{routing: :local} -> BirdyChat.MessageWriter.write(changeset.changes)
|
||||
|
|
@ -6,13 +20,13 @@ defmodule BirdyChat.Dispatcher do
|
|||
end
|
||||
end
|
||||
|
||||
def send_to_remote(%{server: server, to: to} = message) do
|
||||
{_name, base_url} =
|
||||
defp send_to_remote(%{server: server, from: from} = message) do
|
||||
{name, base_url} =
|
||||
BirdyChat.Identity.peers()
|
||||
|> Enum.find(fn {name, _url} -> name == server end)
|
||||
|
||||
api_url = base_url <> "/api/internal"
|
||||
token = Phoenix.Token.sign(BirdyChatWeb.Endpoint, "serverAuth", to)
|
||||
token = Phoenix.Token.sign(BirdyChatWeb.Endpoint, "serverAuth", from)
|
||||
|
||||
{_request, result} =
|
||||
Req.new(url: api_url, retry: false, method: :post)
|
||||
|
|
@ -24,6 +38,12 @@ defmodule BirdyChat.Dispatcher do
|
|||
# Handle more when you encounter errors
|
||||
case result do
|
||||
%Req.Response{status: 201} -> :ok
|
||||
# This should never happen under normal circumstances so I am commenting this out but maybe
|
||||
# needs a second look.
|
||||
# %Req.Response{status: 403} -> {:error, "Unauthorised"}
|
||||
|
||||
# Peer is down.
|
||||
%Req.TransportError{reason: :econnrefused} -> {:error, "peer #{name} is unreachable"}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ defmodule BirdyChat.Identity do
|
|||
peers: %{"test2" => "http://localhost:4001"},
|
||||
mode: :test
|
||||
}
|
||||
|
||||
{identity, peers} ->
|
||||
peers = parse_peers(peers)
|
||||
identity = parse_identity(identity)
|
||||
|
||||
%__MODULE__{identity: identity, peers: peers, mode: :connected}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
defmodule BirdyChat.MessageWriter do
|
||||
@moduledoc false
|
||||
@moduledoc """
|
||||
Simple file writer that stores messages in priv folder of Elixir application/release.
|
||||
"""
|
||||
|
||||
@spec write(%{to: String.t(), from: String.t(), message: String.t()}) :: :ok
|
||||
def write(message) do
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ defmodule BirdyChatWeb.Api.Messages.Controller do
|
|||
|> put_status(:created)
|
||||
|> render(:create, message: changeset.changes)
|
||||
|
||||
:error ->
|
||||
{:error, error} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> render(:error, changeset: changeset)
|
||||
|> render(:error, message: error)
|
||||
end
|
||||
|
||||
{:error, changeset} ->
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ defmodule BirdyChatWeb.Api.Messages.JSON do
|
|||
message
|
||||
end
|
||||
|
||||
def render("error.json", %{message: message}) do
|
||||
%{errors: %{"general" => Gettext.dgettext(BirdyChatWeb.Gettext, "errors", message, [])}}
|
||||
end
|
||||
|
||||
def render("error.json", %{changeset: changeset}) do
|
||||
errors = Ecto.Changeset.traverse_errors(changeset, &get_error/1)
|
||||
%{errors: errors}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue