loqui v0.4.5 Loqui.Client View Source

A high performance client for the Loqui protocol

This client exposes five public functions, start_link, request, push, ping and close. In loqui parlance, request is a synchronous call and push is asynchrounous. Be careful with push calls, as they can overwhelm the remote server.

Codecs and Compressors

A codec changes data structures into iodata and a compressor applies a compression algorithm to iodata. They’re applied thusly:

term
|> Codec.encode()
|> Compressor.compress()

When connecting, a Loqui client and server negotiate which compressors and codecs they should use to communicate.

The Loqui client comes with several preinstalled codecs and compressors. They are:

Codecs

Compressors

The dependencies for the JSON and Msgpack codecs are not automatically resolved. If you wish to use one of them, you need to update your app’s mix.exs.

# in your mix.exs
{:jiffy, "~> 0.14.11"}, # adding this line downloads jiffy and enables the Json codec
{:msgpax, "~> 2.0"}, # adding this line downloads msgpax and enables the Msgpack codec

If Loqui can detect the presence of the modules, then the codecs will be enabled.

Defining your own

If you need to define your own codec or compressor, you’ll need to implement a module and then tell the client about it. In order to define one, implement the behaviour:

defmodule Useless do
  @behaviour Loqui.Protocol.Codec

  def name(), do: "useless"
  def encode(term), do: "1"
  def decode(binary), do: 1
end

Then you need to tell the client to use your codec.

{:ok, client} = Loqui.Client.start_link("localhost", 1234, "/_rpc", loqui_opts: [codecs: [Useless]])

During negotiation, codecs and compressors defined by the user take precedence over the defaults, so if the server supports the Useless codec, it will be the one selected. If not, the precedence is: Erlpack, Msgpack, Json. You can override this ordering by re-specifying the default compressors:

alias Loqui.Protocol.Codecs.{Erlpack, Json, Msgpack}
# Starts a Loqui client on port 4450 favoring the Json codec, then the Msgpack codec, then the Erlpack codec.
{:ok, json_client} = Loqui.Client.start_link("localhost", 4450, "/_rpc", loqui_opts: [codecs: [Json, Msgpack, Erlpack]])

Link to this section Summary

Functions

Closes the connection

Synchronously pings the server

Makes an asynchronous request to the server

Makes a synchronous request to the server

Creates a connection to a Loqui server

Link to this section Types

Link to this type loqui_opt() View Source
loqui_opt() ::
  {:codecs, [Loqui.Protocol.Codec.t()]}
  | {:compressors, [Loqui.Protocol.Compressor.t()]}
Link to this type loqui_opts() View Source
loqui_opts() :: [loqui_opt()]
Link to this type opts() View Source
opts() :: [loqui_opts: loqui_opts(), tcp_opts: tcp_opts()]
Link to this type sequence() View Source
sequence() :: 1..4_294_967_295
Link to this type tcp_opt() View Source
tcp_opt() :: {:recv_timeout, pos_integer()} | {:send_timeout, pos_integer()}
Link to this type tcp_opts() View Source
tcp_opts() :: [tcp_opt()]

Link to this section Functions

Link to this function close(conn, timeout \\ 5000) View Source
close(pid(), pos_integer()) :: :ok | {:error, term()}

Closes the connection.

Link to this function ping(conn, timeout \\ 5000) View Source
ping(pid(), pos_integer()) :: :ok | {:error, term()}

Synchronously pings the server.

Link to this function push(conn, payload) View Source
push(pid(), term()) :: :ok

Makes an asynchronous request to the server.

push sends a request to the server, but doesn’t wait for a reply before returning. This is good for one-off messages, but it’s it’s important to be cognizant that you don’t overwhelm the server with requests, as there’s no backpressure.

Link to this function request(conn, payload, timeout \\ 5000) View Source
request(pid(), term(), pos_integer()) :: {:ok, term()} | {:error, term()}

Makes a synchronous request to the server.

Sends the payload to the server and awaits a response.

Link to this function start_link(host, port, loqui_path, options) View Source
start_link(String.t(), pos_integer(), String.t(), opts()) ::
  {:ok, pid()} | {:error, term()}

Creates a connection to a Loqui server.