freddy v0.12.0 Freddy.RPC.Client behaviour

This module allows to build RPC client for any Freddy-compliant microservice.

Example

defmodule PaymentsService do
  use Freddy.RPC.Client

  @config [timeout: 3500]

  def start_link(conn, initial, opts \\ []) do
    Freddy.RPC.Client.start_link(__MODULE__, conn, @config, initial, opts)
  end
end

{:ok, client} = PaymentsService.start_link()
PaymentsService.request(client, "Payments", %{type: "get_history", site_id: "xxx"})

Link to this section Summary

Functions

Performs a RPC request and blocks until the response arrives

Starts a Freddy.RPC.Client process without linking to the current process, see start_link/5 for more information

Starts a Freddy.RPC.Client process linked to the current process

Callbacks

Called before a request will be performed to the exchange

Called when a response message is delivered from the queue before passing it into a on_response function

Called before a message will be published to the exchange

Called when the process receives a call message sent by call/3. This callback has the same arguments as the GenServer equivalent and the :reply, :noreply and :stop return tuples behave the same

Called when the process receives a cast message sent by cast/2. This callback has the same arguments as the GenServer equivalent and the :noreply and :stop return tuples behave the same

Called when the RPC client process has opened AMQP channel before registering itself as a consumer

Called when the AMQP server has been disconnected from the AMQP broker

Called when the process receives a message. This callback has the same arguments as the GenServer equivalent and the :noreply and :stop return tuples behave the same

Called when the AMQP server has registered the process as a consumer of the server-named queue and it will start to receive messages

Called when the RPC client process is first started. start_link/5 will block until it returns

Called when a response has been received, before it is delivered to the caller

Called when a request has been returned by AMPQ broker

Called when a request has timed out

This callback is the same as the GenServer equivalent and is called when the process terminates. The first argument is the reason the process is about to exit with

Link to this section Types

Link to this type config()
config() :: [timeout: timeout(), exchange: Keyword.t()]
Link to this type meta()
meta() :: map()
Link to this type opts()
opts() :: Keyword.t()
Link to this type payload()
payload() :: term()
Link to this type request()
request() :: Freddy.RPC.Request.t()
Link to this type response()
response() :: term()
Link to this type routing_key()
routing_key() :: String.t()
Link to this type state()
state() :: term()

Link to this section Functions

Link to this function call(client, message, timeout \\ 5000)
Link to this function cast(client, message)
Link to this function request(client, routing_key, payload, opts \\ [])
request(GenServer.server(), routing_key(), payload(), GenServer.options()) ::
  {:ok, response()}
  | {:error, reason :: term()}
  | {:error, reason :: term(), hint :: term()}

Performs a RPC request and blocks until the response arrives.

Link to this function start(mod, conn, config, initial, opts \\ [])
start(
  module(),
  GenServer.server(),
  config(),
  initial :: term(),
  GenServer.options()
) :: GenServer.on_start()

Starts a Freddy.RPC.Client process without linking to the current process, see start_link/5 for more information.

Link to this function start_link(mod, conn, config, initial, opts \\ [])
start_link(
  module(),
  GenServer.server(),
  config(),
  initial :: term(),
  GenServer.options()
) :: GenServer.on_start()

Starts a Freddy.RPC.Client process linked to the current process.

This function is used to start a Freddy.RPC.Client process in a supervision tree. The process will be started by calling init/1 with the given initial value.

Arguments:

  • mod - the module that defines the server callbacks (like GenServer)
  • conn - the pid of a Freddy.Connection process
  • config - the configuration of the RPC Client (describing the exchange and timeout value)
  • initial - the value that will be given to init/1
  • opts - the GenServer options
Link to this function stop(client, reason \\ :normal)

Link to this section Callbacks

Link to this callback before_request(request, state)
before_request(request(), state()) ::
  {:ok, state()}
  | {:ok, request(), state()}
  | {:reply, response(), state()}
  | {:stop, reason :: term(), response(), state()}
  | {:stop, reason :: term(), state()}

Called before a request will be performed to the exchange.

It receives as argument the RPC request structure which contains the message payload, the routing key and the options for that publication, and the internal client state.

Returning {:ok, state} will cause the request to be performed with no modification, block the client until the response is received, and enter the main loop with the given state.

Returning {:ok, request, state} will cause the payload, routing key and options from the given request to be used instead of the original ones, block the client until the response is received, and enter the main loop with the given state.

Returning {:reply, response, state} will respond the client inmediately without performing the request with the given response, and enter the main loop again with the given state.

Returning {:stop, reason, response, state} will not send the message, respond to the caller with response, terminate the main loop and call terminate/2 before the process exits with reason reason.

Returning {:stop, reason, state} will not send the message, terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback decode_response(payload, meta, request, state)
decode_response(payload :: String.t(), meta(), request(), state()) ::
  {:ok, payload(), state()}
  | {:ok, payload(), meta(), state()}
  | {:reply, reply :: term(), state()}
  | {:reply, reply :: term(), state(), timeout() | :hibernate}
  | {:noreply, state()}
  | {:stop, reason :: term(), state()}

Called when a response message is delivered from the queue before passing it into a on_response function.

The arguments are the message’s raw payload, response metatdata, original RPC request for which the response has arrived, and the internal state.

The metadata is a map containing all metadata given by the AMQP client when receiving the message plus the :exchange and :queue values.

Returning {:ok, payload, state} or {:ok, payload, meta, state} will pass the decoded payload and meta into handle_message/3 function.

Returning {:noreply, state} will do nothing, and therefore the message should be acknowledged by using Freddy.Consumer.ack/2, Freddy.Consumer.nack/2 or Freddy.Consumer.reject/2.

Returning {:stop, reason, state} will terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback encode_request(request, state)
encode_request(request(), state()) ::
  {:ok, request(), state()}
  | {:reply, response(), state()}
  | {:reply, response(), state(), timeout() | :hibernate}
  | {:stop, reason :: term(), response(), state()}
  | {:stop, reason :: term(), state()}

Called before a message will be published to the exchange.

It receives as argument the RPC request structure and the internal state.

Returning {:ok, request, state} will cause the returned request to be published to the exchange, and the process to enter the main loop with the given state.

Returning {:reply, response, state} will respond the client inmediately without performing the request with the given response, and enter the main loop again with the given state.

Returning {:stop, reason, response, state} will not send the message, respond to the caller with response, and terminate the main loop and call terminate/2 before the process exits with reason reason.

Returning {:stop, reason, state} will not send the message, terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback handle_call(request, arg1, state)
handle_call(request :: term(), GenServer.from(), state()) ::
  {:reply, reply :: term(), state()}
  | {:reply, reply :: term(), state(), timeout() | :hibernate}
  | {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), state()}
  | {:stop, reason :: term(), reply :: term(), state()}

Called when the process receives a call message sent by call/3. This callback has the same arguments as the GenServer equivalent and the :reply, :noreply and :stop return tuples behave the same.

Link to this callback handle_cast(request, state)
handle_cast(request :: term(), state()) ::
  {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), state()}

Called when the process receives a cast message sent by cast/2. This callback has the same arguments as the GenServer equivalent and the :noreply and :stop return tuples behave the same.

Link to this callback handle_connected(arg0, state)
handle_connected(Freddy.Consumer.connection_info(), state()) ::
  {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:error, state()}
  | {:stop, reason :: term(), state()}

Called when the RPC client process has opened AMQP channel before registering itself as a consumer.

First argument is a map, containing :channel, :exchange and :queue structures.

Returning {:noreply, state} will cause the process to enter the main loop with the given state.

Returning {:error, state} will cause the process to reconnect (i.e. open new channel, declare exchange and queue, etc).

Returning {:stop, reason, state} will terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback handle_disconnected(reason, state)
handle_disconnected(reason :: term(), state()) ::
  {:noreply, state()} | {:stop, reason :: term(), state()}

Called when the AMQP server has been disconnected from the AMQP broker.

Returning {:noreply, state} will cause the process to enter the main loop with the given state. The server will not consume any new messages until connection to AMQP broker is restored.

Returning {:stop, reason, state} will terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback handle_info(message, state)
handle_info(message :: term(), state()) ::
  {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), state()}

Called when the process receives a message. This callback has the same arguments as the GenServer equivalent and the :noreply and :stop return tuples behave the same.

Link to this callback handle_ready(meta, state)
handle_ready(meta(), state()) ::
  {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), state()}

Called when the AMQP server has registered the process as a consumer of the server-named queue and it will start to receive messages.

Returning {:noreply, state} will causes the process to enter the main loop with the given state.

Returning {:stop, reason, state} will not send the message, terminate the main loop and call terminate/2 before the process exits with reason reason.

Link to this callback init(initial)
init(initial :: term()) :: {:ok, state()} | :ignore | {:stop, reason :: term()}

Called when the RPC client process is first started. start_link/5 will block until it returns.

It receives as argument the fourth argument given to start_link/5.

Returning {:ok, state} will cause start_link/5 to return {:ok, pid} and attempt to open a channel on the given connection, declare the exchange, declare a server-named queue, and consume it. After that it will enter the main loop with state as its internal state.

Returning :ignore will cause start_link/5 to return :ignore and the process will exit normally without entering the loop, opening a channel or calling terminate/2.

Returning {:stop, reason} will cause start_link/5 to return {:error, reason} and the process will exit with reason reason without entering the loop, opening a channel, or calling terminate/2.

Link to this callback on_response(response, request, state)
on_response(response(), request(), state()) ::
  {:reply, response(), state()}
  | {:reply, response(), state(), timeout() | :hibernate}
  | {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), response(), state()}
  | {:stop, reason :: term(), state()}

Called when a response has been received, before it is delivered to the caller.

It receives as argument the decoded and parse response, original RPC request for which the response has arrived, and the internal state.

Returning {:reply, reply, state} will cause the given reply to be delivered to the caller instead of the original response, and enter the main loop with the given state.

Returning {:noreply, state} will enter the main loop with the given state without responding to the caller (that will eventually timeout or keep blocked forever if the timeout was set to :infinity).

Returning {:stop, reason, reply, state} will deliver the given reply to the caller instead of the original response and call terminate/2 before the process exits with reason reason.

Returning {:stop, reason, state} not reply to the caller and call terminate/2 before the process exits with reason reason.

Link to this callback on_return(request, state)
on_return(request(), state()) ::
  {:reply, response(), state()}
  | {:reply, response(), state(), timeout() | :hibernate}
  | {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), response(), state()}
  | {:stop, reason :: term(), state()}

Called when a request has been returned by AMPQ broker.

Returning {:reply, reply, state} will cause the given reply to be delivered to the caller, and enter the main loop with the given state.

Returning {:noreply, state} will enter the main loop with the given state without responding to the caller (that will eventually timeout or keep blocked forever if the timeout was set to :infinity).

Returning {:stop, reason, reply, state} will deliver the given reply to the caller, and call terminate/2 before the process exits with reason reason.

Returning {:stop, reason, state} will not reply to the caller and call terminate/2 before the process exits with reason reason.

Link to this callback on_timeout(request, state)
on_timeout(request(), state()) ::
  {:reply, response(), state()}
  | {:reply, response(), state(), timeout() | :hibernate}
  | {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate}
  | {:stop, reason :: term(), response(), state()}
  | {:stop, reason :: term(), state()}

Called when a request has timed out.

Returning {:reply, reply, state} will cause the given reply to be delivered to the caller, and enter the main loop with the given state.

Returning {:noreply, state} will enter the main loop with the given state without responding to the caller (that will eventually timeout or keep blocked forever if the timeout was set to :infinity).

Returning {:stop, reason, reply, state} will deliver the given reply to the caller, and call terminate/2 before the process exits with reason reason.

Returning {:stop, reason, state} will not reply to the caller and call terminate/2 before the process exits with reason reason.

Link to this callback terminate(reason, state)
terminate(reason :: term(), state()) :: any()

This callback is the same as the GenServer equivalent and is called when the process terminates. The first argument is the reason the process is about to exit with.