Skip to content

Commit 221a08a

Browse files
committed
Add fetch timings for connected & status
1 parent 41d8482 commit 221a08a

File tree

3 files changed

+86
-65
lines changed

3 files changed

+86
-65
lines changed

lib/components_guide/fetch.ex

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule ComponentsGuide.Fetch do
2-
alias ComponentsGuide.Fetch.{Request, Response}
2+
alias ComponentsGuide.Fetch.{Request, Response, Timings}
33

44
@timeout 5000
55

@@ -10,45 +10,6 @@ defmodule ComponentsGuide.Fetch do
1010
get_following_redirects!(url_string)
1111
end
1212

13-
defmodule Timings do
14-
defstruct [:duration, :start]
15-
16-
def start() do
17-
%__MODULE__{
18-
start: System.monotonic_time()
19-
}
20-
end
21-
22-
def finish(timings = %__MODULE__{start: start}) do
23-
duration = System.monotonic_time() - start
24-
put_in(timings.duration, duration)
25-
end
26-
27-
def start_with_telemetry(event_name, metadata \\ %{}) do
28-
t = start()
29-
30-
:telemetry.execute(
31-
event_name,
32-
%{start: t.start},
33-
metadata
34-
)
35-
36-
t
37-
end
38-
39-
def finish_with_telemetry(t = %__MODULE__{}, event_name, metadata \\ %{}) do
40-
t = finish(t)
41-
42-
:telemetry.execute(
43-
event_name,
44-
%{duration: t.duration},
45-
metadata
46-
)
47-
48-
t
49-
end
50-
end
51-
5213
def get_following_redirects!(url_string) when is_binary(url_string) do
5314
response =
5415
case Request.new(url_string) do
@@ -88,18 +49,14 @@ defmodule ComponentsGuide.Fetch do
8849
t = Timings.start_with_telemetry([:fetch, :load!, :start], %{req: req})
8950

9051
{:ok, conn} = Mint.HTTP.connect(:https, host, 443, mode: :passive, protocols: protocols)
91-
{conn, response} = do_request(conn, req)
52+
t = t |> Timings.did_connect()
53+
{conn, response} = do_request(conn, req, t)
9254
Mint.HTTP.close(conn)
9355

94-
t =
95-
Timings.finish_with_telemetry(t, [:fetch, :load!, :done], %{
96-
req: req
97-
})
98-
99-
response = Response.add_timings(response, t)
56+
response = Response.finish_timings(response, [:fetch, :load!, :done], %{req: req})
10057

10158
IO.puts(
102-
"Loaded #{req.url_string} in #{System.convert_time_unit(t.duration, :native, :millisecond)}ms. #{inspect(response.done?)}"
59+
"Loaded #{req.url_string} in #{System.convert_time_unit(response.timings.duration, :native, :millisecond)}ms. #{inspect(response.done?)}"
10360
)
10461

10562
response
@@ -116,20 +73,16 @@ defmodule ComponentsGuide.Fetch do
11673
t = Timings.start_with_telemetry([:fetch, :load_many!, :start], %{host: host})
11774

11875
{:ok, conn} = Mint.HTTP.connect(:https, host, 443, mode: :passive, protocols: [:http1])
76+
t = t |> Timings.did_connect()
11977

12078
{conn, results} =
12179
Enum.reduce(reqs, {conn, []}, fn
12280
%Request{uri: %URI{host: ^host, port: 443}} = req, {conn, results} ->
12381
t = Timings.start_with_telemetry([:fetch, :load_many!, :request, :start], %{req: req})
12482

125-
{conn, response} = do_request(conn, req)
126-
127-
t =
128-
Timings.finish_with_telemetry(t, [:fetch, :load_many!, :request, :done], %{
129-
req: req
130-
})
83+
{conn, response} = do_request(conn, req, t)
13184

132-
response = Response.add_timings(response, t)
85+
response = Response.finish_timings(response, [:fetch, :load_many!, :request, :done], %{req: req})
13386

13487
{conn, [response | results]}
13588
end)
@@ -162,9 +115,10 @@ defmodule ComponentsGuide.Fetch do
162115
headers: headers,
163116
body: body,
164117
url_string: url_string
165-
}
118+
},
119+
timings = %Timings{}
166120
) do
167-
result = Response.new(url_string)
121+
result = Response.new(url_string, timings)
168122
path_and_query = %URI{path: uri.path || "/", query: uri.query} |> URI.to_string()
169123

170124
case Mint.HTTP.request(conn, method, path_and_query, headers, body) do

lib/components_guide/fetch/response.ex

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
defmodule ComponentsGuide.Fetch.Response do
2-
defstruct done?: false, url: nil, status: nil, headers: [], body: "", error: nil, timings: nil
2+
alias ComponentsGuide.Fetch.Timings
33

4-
def new(url_string) do
5-
%__MODULE__{url: url_string, done?: false}
4+
defstruct done?: false,
5+
url: nil,
6+
status: nil,
7+
headers: [],
8+
body: "",
9+
error: nil,
10+
timings: %Timings{}
11+
12+
def new(url_string, timings = %Timings{}) do
13+
%__MODULE__{url: url_string, done?: false, timings: timings}
614
end
715

816
def failed(url_string, error) do
9-
new(url_string) |> add_error(error)
17+
new(url_string, nil) |> add_error(error)
1018
end
1119

1220
def add_responses(receiver = %__MODULE__{}, responses, ref) do
1321
Enum.reduce(responses, receiver, fn
1422
{:status, ^ref, code}, acc ->
1523
IO.puts("status #{code}")
16-
Map.put(acc, :status, code)
24+
25+
acc
26+
|> Map.update!(:timings, &Timings.did_receive_status/1)
27+
|> Map.put(:status, code)
1728

1829
{:headers, ^ref, headers}, acc ->
1930
IO.puts("headers")
20-
Map.update(acc, :headers, headers, &(&1 ++ headers))
31+
32+
acc
33+
|> Map.update!(:timings, &Timings.did_receive_headers/1)
34+
|> Map.update(:headers, headers, &(&1 ++ headers))
2135

2236
{:data, ^ref, data}, acc ->
2337
IO.puts("data")
@@ -29,8 +43,8 @@ defmodule ComponentsGuide.Fetch.Response do
2943
end)
3044
end
3145

32-
def add_timings(receiver = %__MODULE__{}, timings) do
33-
put_in(receiver.timings, timings)
46+
def finish_timings(receiver = %__MODULE__{}, event_name, metadata \\ %{}) do
47+
update_in(receiver.timings, &Timings.finish_with_telemetry(&1, event_name, metadata))
3448
end
3549

3650
def add_error(receiver = %__MODULE__{}, error) do

lib/components_guide/fetch/timings.ex

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
defmodule ComponentsGuide.Fetch.Timings do
2+
defstruct [:start, :connected, :received_status, :received_headers, :duration]
3+
4+
def start() do
5+
%__MODULE__{
6+
start: System.monotonic_time()
7+
}
8+
end
9+
10+
def did_connect(timings = %__MODULE__{start: start}) do
11+
duration = System.monotonic_time() - start
12+
put_in(timings.connected, duration)
13+
end
14+
15+
def did_receive_status(timings = %__MODULE__{start: start}) do
16+
duration = System.monotonic_time() - start
17+
put_in(timings.received_status, duration)
18+
end
19+
20+
def did_receive_headers(timings = %__MODULE__{start: start}) do
21+
duration = System.monotonic_time() - start
22+
put_in(timings.received_headers, duration)
23+
end
24+
25+
def finish(timings = %__MODULE__{start: start}) do
26+
duration = System.monotonic_time() - start
27+
put_in(timings.duration, duration)
28+
end
29+
30+
def start_with_telemetry(event_name, metadata \\ %{}) do
31+
t = start()
32+
33+
:telemetry.execute(
34+
event_name,
35+
%{start: t.start},
36+
metadata
37+
)
38+
39+
t
40+
end
41+
42+
def finish_with_telemetry(t = %__MODULE__{}, event_name, metadata \\ %{}) do
43+
t = finish(t)
44+
45+
:telemetry.execute(
46+
event_name,
47+
%{duration: t.duration},
48+
metadata
49+
)
50+
51+
t
52+
end
53+
end

0 commit comments

Comments
 (0)