Packages
timber
3.1.0
3.1.2
3.1.1
3.1.0
3.0.0
3.0.0-alpha.3
3.0.0-alpha.2
3.0.0-alpha.1
2.8.4
2.8.3
2.8.2
2.8.1
2.8.0
2.7.0
2.6.1
2.6.0
2.5.6
2.5.5
2.5.4
2.5.3
2.5.2
2.5.1
2.5.0
2.4.5
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.4
2.3.3
2.3.1
2.3.0
2.2.1
2.2.0
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
2.0.0-rc7
2.0.0-rc6
2.0.0-rc5
2.0.0-rc4
2.0.0-rc3
2.0.0-rc2
2.0.0-rc1
1.1.18
1.1.17
1.1.16
1.1.15
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
🌲 Great Elixir Logging Made Easy. Official Timber.io Integration.
Current section
Files
Jump to
Current section
Files
lib/timber/http_clients/hackney.ex
defmodule Timber.HTTPClients.Hackney do
@moduledoc false
# An efficient HTTP client that leverages hackney, keep alive connections, and connection
# pools to communicate with the Timber API.
# ## Configuration
# ```elixir
# config :timber, :hackney_client,
# request_options: [
# connect_timeout: 5_000, # 5 seconds, timeout to connect
# recv_timeout: 20_000 # 20 seconds, timeout to receive a response
# ]
# ```
# * `:request_options` - Passed to `:hackney.request(method, url, headers, body, request_options)`.
alias Timber.HTTPClient
@behaviour HTTPClient
@default_request_options [
# 5 seconds, timeout to connect
connect_timeout: 5_000,
# 10 seconds, timeout to receive a response
recv_timeout: 10_000
]
@doc false
@impl HTTPClient
def async_request(method, url, headers, body) do
req_headers = Enum.map(headers, & &1)
req_opts =
get_request_options()
|> Keyword.merge(async: true)
:hackney.request(method, url, req_headers, body, req_opts)
end
@doc false
@impl HTTPClient
# Legacy response structure for older versions of `:hackney`
def handle_async_response(ref, {:hackney_response, ref, {:ok, status, _body}}) do
{:ok, status}
end
# New response structure for current versions of `:hackney`
def handle_async_response(ref, {:hackney_response, ref, {:status, status, _body}}) do
{:ok, status}
end
# New response structure for current versions of `:hackney`
def handle_async_response(ref, {:hackney_response, ref, {:status, status}}) do
{:ok, status}
end
# Return errors since that conforms to the spec
def handle_async_response(ref, {:hackney_response, ref, {:error, _error} = error_tuple}) do
error_tuple
end
# Pass other messages
def handle_async_response(_ref, _msg) do
:pass
end
@doc false
@impl HTTPClient
def wait_on_response(ref, timeout) do
receive do
{:hackney_response, ^ref, _response} = msg ->
handle_async_response(ref, msg)
after
timeout ->
:timeout
end
end
@doc false
@impl HTTPClient
def request(method, url, headers, body) do
req_headers = Enum.map(headers, & &1)
req_opts =
get_request_options()
|> Keyword.merge(with_body: true)
:hackney.request(method, url, req_headers, body, req_opts)
end
#
# Config
#
@spec config :: Keyword.t()
defp config, do: Application.get_env(:timber, :hackney_client, [])
@spec get_request_options() :: Keyword.t()
defp get_request_options(),
do: Keyword.get(config(), :request_options, @default_request_options)
end