Skip to content

Commit 1d10974

Browse files
authored
Merge pull request #241 from plausible/remove-mint-timeout
Remove Mint timeout
2 parents cb20e65 + 3da4ee8 commit 1d10974

File tree

4 files changed

+42
-32
lines changed

4 files changed

+42
-32
lines changed

lib/ch.ex

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ defmodule Ch do
77
| {:username, String.t()}
88
| {:password, String.t()}
99
| {:settings, Keyword.t()}
10-
| {:timeout, timeout}
1110

1211
@type start_option ::
1312
common_option
1413
| {:scheme, String.t()}
1514
| {:hostname, String.t()}
1615
| {:port, :inet.port_number()}
17-
| {:transport_opts, [:gen_tcp.connect_option() | :ssl.client_option()]}
16+
| {:transport_opts, [:gen_tcp.connect_option() | :ssl.tls_client_option()]}
17+
| {:timeout, timeout}
1818
| DBConnection.start_option()
1919

2020
@doc """
@@ -30,8 +30,8 @@ defmodule Ch do
3030
* `:username` - Username
3131
* `:password` - User password
3232
* `:settings` - Keyword list of ClickHouse settings
33-
* `:timeout` - HTTP receive timeout in milliseconds
3433
* `:transport_opts` - options to be given to the transport being used. See `Mint.HTTP1.connect/4` for more info
34+
* `:timeout` - Connection handshake and ping timeout in milliseconds
3535
* [`DBConnection.start_option()`](https://hexdocs.pm/db_connection/DBConnection.html#t:start_option/0)
3636
3737
"""
@@ -72,7 +72,6 @@ defmodule Ch do
7272
* `:username` - Username
7373
* `:password` - User password
7474
* `:settings` - Keyword list of settings
75-
* `:timeout` - Query request timeout
7675
* `:command` - Command tag for the query
7776
* `:headers` - Custom HTTP headers for the request
7877
* `:format` - Custom response format for the request

lib/ch/connection.ex

+22-18
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ defmodule Ch.Connection do
1414
def connect(opts) do
1515
with {:ok, conn} <- do_connect(opts) do
1616
handshake = Query.build("select 1")
17-
params = DBConnection.Query.encode(handshake, _params = [], _opts = [])
1817

19-
case handle_execute(handshake, params, _opts = [], conn) do
20-
{:ok, handshake, responses, conn} ->
18+
{query_params, extra_headers, body} =
19+
DBConnection.Query.encode(handshake, _params = [], _opts = [])
20+
21+
path = path(conn, query_params, opts)
22+
headers = headers(conn, extra_headers, opts)
23+
timeout = HTTP.get_private(conn, :timeout) || :timer.seconds(15)
24+
25+
case request(conn, "POST", path, headers, body, timeout) do
26+
{:ok, conn, responses} ->
2127
case DBConnection.Query.decode(handshake, responses, _opts = []) do
2228
%Result{rows: [[1]]} ->
2329
{:ok, conn}
@@ -44,8 +50,9 @@ defmodule Ch.Connection do
4450
def ping(conn) do
4551
conn = maybe_reconnect(conn)
4652
headers = [{"user-agent", @user_agent}]
53+
timeout = HTTP.get_private(conn, :timeout) || :timer.seconds(5)
4754

48-
case request(conn, "GET", "/ping", headers, _body = "", _opts = []) do
55+
case request(conn, "GET", "/ping", headers, _body = [], timeout) do
4956
{:ok, conn, _response} -> {:ok, conn}
5057
{:error, error, conn} -> {:disconnect, error, conn}
5158
{:disconnect, _error, _conn} = disconnect -> disconnect
@@ -88,7 +95,7 @@ defmodule Ch.Connection do
8895
headers = headers(conn, extra_headers, opts)
8996

9097
with {:ok, conn, _ref} <- send_request(conn, "POST", path, headers, body),
91-
{:ok, conn} <- eat_ok_status_and_headers(conn, timeout(conn, opts)) do
98+
{:ok, conn} <- eat_ok_status_and_headers(conn, :infinity) do
9299
{:ok, query, %Result{command: command}, conn}
93100
end
94101
end
@@ -148,8 +155,8 @@ defmodule Ch.Connection do
148155
end
149156
end
150157

151-
def handle_fetch(_query, result, opts, conn) do
152-
case HTTP.recv(conn, 0, timeout(conn, opts)) do
158+
def handle_fetch(_query, result, _opts, conn) do
159+
case HTTP.recv(conn, 0, :infinity) do
153160
{:ok, conn, responses} ->
154161
{halt_or_cont(responses), %Result{result | data: extract_data(responses)}, conn}
155162

@@ -194,12 +201,12 @@ defmodule Ch.Connection do
194201
end
195202
end
196203

197-
def handle_execute(%Query{} = query, {:stream, ref, body}, opts, conn) do
204+
def handle_execute(%Query{} = query, {:stream, ref, body}, _opts, conn) do
198205
case HTTP.stream_request_body(conn, ref, body) do
199206
{:ok, conn} ->
200207
case body do
201208
:eof ->
202-
with {:ok, conn, responses} <- receive_full_response(conn, timeout(conn, opts)) do
209+
with {:ok, conn, responses} <- receive_full_response(conn, :infinity) do
203210
{:ok, query, responses, conn}
204211
end
205212

@@ -219,7 +226,7 @@ defmodule Ch.Connection do
219226
path = path(conn, query_params, opts)
220227
headers = headers(conn, extra_headers, opts)
221228

222-
with {:ok, conn, responses} <- request(conn, "POST", path, headers, body, opts) do
229+
with {:ok, conn, responses} <- request(conn, "POST", path, headers, body, :infinity) do
223230
{:ok, query, responses, conn}
224231
end
225232
end
@@ -232,13 +239,13 @@ defmodule Ch.Connection do
232239

233240
@typep response :: Mint.Types.status() | Mint.Types.headers() | binary
234241

235-
@spec request(conn, binary, binary, Mint.Types.headers(), iodata, [Ch.query_option()]) ::
242+
@spec request(conn, binary, binary, Mint.Types.headers(), iodata, timeout) ::
236243
{:ok, conn, [response]}
237244
| {:error, Error.t(), conn}
238245
| {:disconnect, Mint.Types.error(), conn}
239-
defp request(conn, method, path, headers, body, opts) do
246+
defp request(conn, method, path, headers, body, timeout) do
240247
with {:ok, conn, _ref} <- send_request(conn, method, path, headers, body) do
241-
receive_full_response(conn, timeout(conn, opts))
248+
receive_full_response(conn, timeout)
242249
end
243250
end
244251

@@ -275,7 +282,7 @@ defmodule Ch.Connection do
275282
end
276283
end
277284

278-
@spec recv_all(conn, [response], timeout()) ::
285+
@spec recv_all(conn, [response], timeout) ::
279286
{:ok, conn, [response]} | {:disconnect, Mint.Types.error(), conn}
280287
defp recv_all(conn, acc, timeout) do
281288
case HTTP.recv(conn, 0, timeout) do
@@ -302,9 +309,6 @@ defmodule Ch.Connection do
302309
defp maybe_put_private(conn, _k, nil), do: conn
303310
defp maybe_put_private(conn, k, v), do: HTTP.put_private(conn, k, v)
304311

305-
defp timeout(conn), do: HTTP.get_private(conn, :timeout)
306-
defp timeout(conn, opts), do: Keyword.get(opts, :timeout) || timeout(conn)
307-
308312
defp settings(conn, opts) do
309313
default_settings = HTTP.get_private(conn, :settings, [])
310314
opts_settings = Keyword.get(opts, :settings, [])
@@ -375,7 +379,7 @@ defmodule Ch.Connection do
375379
with {:ok, conn} <- HTTP.connect(scheme, address, port, mint_opts) do
376380
conn =
377381
conn
378-
|> HTTP.put_private(:timeout, opts[:timeout] || :timer.seconds(15))
382+
|> maybe_put_private(:timeout, opts[:timeout])
379383
|> maybe_put_private(:database, opts[:database])
380384
|> maybe_put_private(:username, opts[:username])
381385
|> maybe_put_private(:password, opts[:password])

test/ch/connection_test.exs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1247,13 +1247,15 @@ defmodule Ch.ConnectionTest do
12471247
end
12481248

12491249
describe "options" do
1250-
# this test is flaky, sometimes it raises due to ownership timeout
1251-
@tag capture_log: true, skip: true
12521250
test "can provide custom timeout", %{conn: conn} do
1253-
assert {:error, %Mint.TransportError{reason: :timeout} = error} =
1254-
Ch.query(conn, "select sleep(1)", _params = [], timeout: 100)
1251+
log =
1252+
ExUnit.CaptureLog.capture_log([async: true], fn ->
1253+
assert {:error, %Mint.TransportError{reason: :closed}} =
1254+
Ch.query(conn, "select sleep(1)", _params = [], timeout: 100)
1255+
end)
12551256

1256-
assert Exception.message(error) == "timeout"
1257+
assert log =~
1258+
"timed out because it queued and checked out the connection for longer than 100ms"
12571259
end
12581260

12591261
test "errors on invalid creds", %{conn: conn} do

test/ch/faults_test.exs

+10-5
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ defmodule Ch.FaultsTest do
254254

255255
log =
256256
capture_async_log(fn ->
257-
{:ok, conn} = Ch.start_link(port: port, timeout: 100)
257+
{:ok, conn} = Ch.start_link(port: port)
258258

259259
# connect
260260
{:ok, mint} = :gen_tcp.accept(listen)
@@ -264,8 +264,8 @@ defmodule Ch.FaultsTest do
264264
:ok = :gen_tcp.send(mint, intercept_packets(clickhouse))
265265

266266
spawn_link(fn ->
267-
assert {:error, %Mint.TransportError{reason: :timeout}} =
268-
Ch.query(conn, "select 1 + 1")
267+
assert {:error, %Mint.TransportError{reason: :closed}} =
268+
Ch.query(conn, "select 1 + 1", [], timeout: 100)
269269
end)
270270

271271
# failed select 1 + 1
@@ -280,7 +280,9 @@ defmodule Ch.FaultsTest do
280280
:ok = :gen_tcp.send(mint, intercept_packets(clickhouse))
281281

282282
spawn_link(fn ->
283-
assert {:ok, %{num_rows: 1, rows: [[2]]}} = Ch.query(conn, "select 1 + 1")
283+
assert {:ok, %{num_rows: 1, rows: [[2]]}} =
284+
Ch.query(conn, "select 1 + 1", [], timeout: 100)
285+
284286
send(test, :done)
285287
end)
286288

@@ -291,7 +293,10 @@ defmodule Ch.FaultsTest do
291293
assert_receive :done
292294
end)
293295

294-
assert log =~ "disconnected: ** (Mint.TransportError) timeout"
296+
assert log =~ "disconnected: ** (DBConnection.ConnectionError)"
297+
298+
assert log =~
299+
"timed out because it queued and checked out the connection for longer than 100ms"
295300
end
296301

297302
test "reconnects after closed on response", ctx do

0 commit comments

Comments
 (0)