message-server/lib/message_server/remote_client.ex

66 lines
2.2 KiB
Elixir

defmodule MessageServer.RemoteClient do
require Logger
alias MessageServer.{MessageRequest, ServerRegistry, Auth, MessageQueue}
@spec send_message_to_server(String.t(), MessageRequest.t()) :: :ok | {:error, String.t()}
def send_message_to_server(target_server_id, payload) do
with {:ok, server_info} <- ServerRegistry.get_server_info(target_server_id),
{:ok, serialized_payload} <- serialize_payload(payload),
{:ok, response} <- make_request(server_info, serialized_payload) do
handle_response(response)
else
{:error, :not_found} ->
{:error, "Unknown server: #{target_server_id}"}
{:error, reason} = error ->
Logger.error("Failed to send message to server #{target_server_id}: #{reason}")
MessageQueue.queue_message(target_server_id, payload)
error
end
end
@spec serialize_payload(MessageRequest.t()) :: {:ok, binary()} | {:error, String.t()}
defp serialize_payload(payload) do
try do
serialized = :erlang.term_to_binary(payload)
{:ok, serialized}
rescue
error -> {:error, "Serialization failed: #{inspect(error)}"}
end
end
@spec make_request(map(), binary()) :: {:ok, Req.Response.t()} | {:error, String.t()}
defp make_request(%{host: host, port: port}, serialized_payload) do
url = "http://#{host}:#{port}/api/remote/messages"
local_server_id = ServerRegistry.get_server_id()
auth_token = Auth.generate_auth_token(local_server_id)
case Req.post(url,
body: serialized_payload,
headers: [
{"content-type", "application/octet-stream"},
{"authorization", "Bearer #{auth_token}"}
]
) do
{:ok, %Req.Response{status: status} = response} when status in 200..299 ->
{:ok, response}
{:ok, %Req.Response{status: status}} ->
{:error, "HTTP #{status}"}
{:error, reason} ->
{:error, "Request failed: #{inspect(reason)}"}
end
end
@spec handle_response(Req.Response.t()) :: :ok | {:error, String.t()}
defp handle_response(%Req.Response{body: body}) do
case body do
%{"status" => "success"} -> :ok
%{"error" => error} -> {:error, error}
_ -> {:error, "Invalid response format"}
end
end
end