Packages

Process pool based HTTP1/2 and Websocket client

Current section

5 Versions

Jump to

Compare versions

8 files changed
+59 additions
-30 deletions
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/OdielDomanie/tulle">>}]}.
2 2 {<<"name">>,<<"tulle">>}.
3 - {<<"version">>,<<"0.6.3">>}.
3 + {<<"version">>,<<"0.7.0">>}.
4 4 {<<"description">>,<<"Process pool based HTTP1/2 and Websocket client">>}.
5 5 {<<"elixir">>,<<"~> 1.15">>}.
6 6 {<<"app">>,<<"tulle">>}.
  @@ -1,6 +1,6 @@
1 - defmodule Tulle.Http do
1 + defmodule Tulle.HTTP do
2 2 @moduledoc """
3 - Make HTTP2 requests with a `DiscordEx.Http2.Client`.
3 + Make HTTP requests with a `Tulle.HTTP1.Client` or `Tulle.HTTP2.Client`.
4 4 """
5 5
6 6 alias __MODULE__.Request
  @@ -8,13 +8,21 @@ defmodule Tulle.Http do
8 8 @typedoc """
9 9 A `Collectable` that writes to an HTTP request stream.
10 10
11 - Created with `request_collectable/3`.
11 + Created with `request_collectable!/2`.
12 12 When done sending, `close_request!/1` must be called to signal the EOF.
13 13 """
14 14 @opaque request :: %Request{client: client(), ref: Mint.Types.request_ref(), info: any}
15 15
16 - @type client :: GenServer.server()
16 + @typedoc """
17 + A `Tulle.HTTP1.Client` or `Tulle.HTTP2.Client` or process.
18 + """
19 + @type client :: Tulle.HTTP1.Client.http1_client() | Tulle.HTTP2.Client.http2_client()
17 20
21 + @typedoc """
22 + Method-path-header triple.
23 +
24 + req_params(atom) would indicate method can be either a string or atom.
25 + """
18 26 @type req_params(method_alt) ::
19 27 {method :: String.t() | method_alt, path :: String.t(), Mint.Types.headers()}
20 28
  @@ -45,6 +53,12 @@ defmodule Tulle.Http do
45 53 end
46 54
47 55 @spec request_collectable!(client, req_params(atom)) :: request()
56 + @doc """
57 + Start a streaming request.
58 +
59 + The returned `t:request/0` object can be `Enum.into/2`'ed.
60 + Call `close_request!/1` to signal the EOF.
61 + """
48 62 def request_collectable!(client, {method, path, headers}) do
49 63 method = method |> to_string() |> String.upcase()
50 64
  @@ -57,7 +71,7 @@ defmodule Tulle.Http do
57 71 @spec close_request!(request()) ::
58 72 {pos_integer(), Mint.Types.headers(), iodata_stream :: Enum.t()}
59 73 @doc """
60 - Sends EOF for the collectable returned by `request_collectable!/3`.
74 + Sends EOF for the collectable returned by `request_collectable!/2`.
61 75
62 76 Returns a triple of the status, the headers, and the response body stream.
63 77 """
  @@ -1,7 +1,8 @@
1 - defmodule Tulle.Http1.Client do
1 + defmodule Tulle.HTTP1.Client do
2 2 @moduledoc """
3 - HTTP1 Client. Used with `Tulle.Http`.
3 + HTTP1 Client. Used with `Tulle.HTTP`.
4 4
5 + Keeps the HTTP connection open
5 6 Tries to reconnect when the connection is lost,
6 7 exits if it can't reconnect with `{:cant_connect, reason}`
7 8 """
  @@ -11,7 +12,7 @@ defmodule Tulle.Http1.Client do
11 12 require Logger
12 13 alias Mint.HTTP1
13 14
14 - @type t :: GenServer.name()
15 + @type http1_client :: GenServer.server()
15 16
16 17 def start_link(opts) do
17 18 connect_args =
  @@ -1,16 +1,21 @@
1 - defmodule Tulle.Http1.Pool do
1 + defmodule Tulle.HTTP1.Pool do
2 + @worker_idle_min 60_000
3 +
2 4 @moduledoc """
3 - Pool used for Http1.
5 + Pool for holding `Tulle.HTTP1.Client` processes.
6 +
7 + In current implementation,
8 + at least one connection (one process) is kept open.
9 + Idle processes are shutdown with a half-life of
10 + #{@worker_idle_min |> div(1_000)} seconds.
4 11 """
5 12
6 13 use GenServer
7 14
8 15 require Logger
9 - alias Tulle.Http1
16 + alias Tulle.HTTP1
10 17
11 - @worker_idle_max 60_000
12 -
13 - @type t :: GenServer.server()
18 + @type pool :: GenServer.server()
14 19 @type worker :: pid
15 20
16 21 def start_link(opts) do
  @@ -20,9 +25,9 @@ defmodule Tulle.Http1.Pool do
20 25 GenServer.start_link(__MODULE__, {opts[:sv], connect_args}, opts)
21 26 end
22 27
23 - @spec check_out!(t, timeout()) :: worker()
28 + @spec check_out!(pool, timeout()) :: worker()
24 29 @doc """
25 - Check-out a `Tulle.Http1.Client` process from the pool,
30 + Check-out a `Tulle.HTTP1.Client` process from the pool,
26 31 spawning if necessary.
27 32 """
28 33 def check_out!(pool, timeout \\ 5000) do
  @@ -30,9 +35,9 @@ defmodule Tulle.Http1.Pool do
30 35 client
31 36 end
32 37
33 - @spec check_in(t, worker()) :: :ok
38 + @spec check_in(pool, worker()) :: :ok
34 39 @doc """
35 - Returns a checked-out `Tulle.Http1.Client` back to the pool.
40 + Returns a checked-out `Tulle.HTTP1.Client` back to the pool.
36 41 """
37 42 def check_in(pool, client) do
38 43 GenServer.call(pool, {:check_in, client})
  @@ -77,7 +82,7 @@ defmodule Tulle.Http1.Pool do
77 82 defp spawn_http1_worker(sv, connect_args) do
78 83 spec =
79 84 Supervisor.child_spec(
80 - {Http1.Client, connect_args},
85 + {HTTP1.Client, connect_args},
81 86 restart: :temporary
82 87 )
83 88
  @@ -89,7 +94,7 @@ defmodule Tulle.Http1.Pool do
89 94 end
90 95
91 96 defp set_timer(worker) do
92 - Process.send_after(self(), {:timer, worker}, @worker_idle_max)
97 + Process.send_after(self(), {:timer, worker}, @worker_idle_min)
93 98 end
94 99
95 100 @impl true
  @@ -1,6 +1,6 @@
1 - defmodule Tulle.Http2.Client do
1 + defmodule Tulle.HTTP2.Client do
2 2 @moduledoc """
3 - HTTP2 Client. Used with `Tulle.Http`.
3 + HTTP2 Client. Used with `Tulle.HTTP`.
4 4 """
5 5 use GenServer
6 6
  @@ -10,7 +10,7 @@ defmodule Tulle.Http2.Client do
10 10 alias Mint.HTTP2
11 11 import Mint.HTTP, only: [is_connection_message: 2]
12 12
13 - @type t :: GenServer.name()
13 + @type http2_client :: GenServer.server()
14 14
15 15 def start_link(opts) do
16 16 GenServer.start_link(
Loading more files…