-
Notifications
You must be signed in to change notification settings - Fork 8
/
client.ex
67 lines (51 loc) · 2.58 KB
/
client.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
defmodule Arangox.Client do
@moduledoc """
HTTP client behaviour for `Arangox`. Arangox uses client implementations to
perform all it's connection and execution operations.
To use an http library other than `:gun` or `:mint`, implement this behaviour
in a module and pass that module to the `:client` start option.
"""
alias Arangox.{
Connection,
Request,
Response
}
@type socket :: any
@type exception_or_reason :: any
@doc """
Receives an `Arangox.Endpoint` struct and all the start options from `Arangox.start_link/1`.
The `socket` returned from this callback gets placed in the `:socket` field
of an `Arango.Connection` struct (a connection's state) to be used by the
other callbacks as needed. It can be anything, a tuple, another struct, whatever
the client needs.
It's up to the client to consolidate the `:connect_timeout`, `:transport_opts`
and `:client_opts` options.
"""
@callback connect(endpoint :: Endpoint.t(), start_options :: [Arangox.start_option()]) ::
{:ok, socket} | {:error, exception_or_reason}
@callback alive?(state :: Connection.t()) :: boolean
@doc """
Receives a `Arangox.Request` struct and a connection's state (an `Arangox.Connection`
struct), and returns an `Arangox.Response` struct or error (or exception struct),
along with the new state (which doesn't necessarily need to change).
Arangox handles the encoding and decoding of request and response bodies, and merging headers.
If a connection is lost, this may return `{:error, :noproc, state}` to force a disconnect,
otherwise an attempt to reconnect may not be made until the next request hitting this process
fails.
"""
@callback request(request :: Request.t(), state :: Connection.t()) ::
{:ok, Response.t(), Connection.t()} | {:error, exception_or_reason, Connection.t()}
@callback close(state :: Connection.t()) :: :ok
# API
@spec connect(module, Endpoint.t(), [Arangox.start_option()]) ::
{:ok, socket} | {:error, exception_or_reason}
def connect(client, endpoint, start_options), do: client.connect(endpoint, start_options)
@spec alive?(Connection.t()) :: boolean
def alive?(%Connection{client: client} = state), do: client.alive?(state)
@spec request(Request.t(), Connection.t()) ::
{:ok, Response.t(), Connection.t()} | {:error, exception_or_reason, Connection.t()}
def request(%Request{} = request, %Connection{client: client} = state),
do: client.request(request, state)
@spec close(Connection.t()) :: :ok
def close(%Connection{client: client} = state), do: client.close(state)
end