Skip to content

Commit c5fc04c

Browse files
authored
Merge pull request #1347 from katafrakt/telemetry-for-batch-timeout
Proposal: Telemetry event instead of predefined log message on batch timeout
2 parents e37e285 + 8898d57 commit c5fc04c

File tree

4 files changed

+49
-15
lines changed

4 files changed

+49
-15
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@
55
- Feature: [Add async option to Absinthe.Subscription](https://github.com/absinthe-graphql/absinthe/pull/1329)
66
- Bug Fix: [Avoid table scans on registry](https://github.com/absinthe-graphql/absinthe/pull/1330)
77
- Big Fix: [Unregsiter duplicate (listening to the same topic) subscriptions individually](https://github.com/absinthe-graphql/absinthe/pull/1336)
8+
- POTENTIALLY BREAKING Feature: [Add telemetry event on batch timeout](https://github.com/absinthe-graphql/absinthe/pull/1347). If you want to keep the behavior from 1.7.8, define a telemetry handler and attach it. For example:
9+
10+
```elixir
11+
defmodule MyApp.Telemetry do
12+
require Logger
13+
14+
def log_absinthe([:absinthe, :middleware, :batch, :timeout], _, metadata, _) do
15+
Logger.error("Failed to get batching result in #{metadata.timeout}ms for\nfn: #{inspect(metadata.fn)}")
16+
end
17+
end
18+
19+
# attach
20+
21+
:telemetry.attach("absinthe-batch-timeout", [:absinthe, :middleware, :batch, :timeout], &MyApp.Telemetry.log_absinthe/4, nil)
22+
```
823
924
## 1.7.8
1025

guides/telemetry.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ handler function to any of the following event names:
1313
- `[:absinthe, :resolve, :field, :stop]` when field resolution finishes
1414
- `[:absinthe, :middleware, :batch, :start]` when the batch processing starts
1515
- `[:absinthe, :middleware, :batch, :stop]` when the batch processing finishes
16+
- `[:absinthe, :middleware, :batch, :timeout]` whe the batch processing times out
1617

1718
Telemetry handlers are called with `measurements` and `metadata`. For details on
1819
what is passed, checkout `Absinthe.Phase.Telemetry`, `Absinthe.Middleware.Telemetry`,

lib/absinthe/middleware/batch.ex

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,16 +162,14 @@ defmodule Absinthe.Middleware.Batch do
162162
result
163163

164164
_ ->
165-
Logger.error(
166-
"Failed to get batching result in #{timeout}ms for\nfn: #{inspect(batch_fun)}"
167-
)
168-
165+
emit_timeout_event(batch_fun, timeout)
169166
Process.exit(self(), :timeout)
170167
end
171168
end
172169

173170
@batch_start [:absinthe, :middleware, :batch, :start]
174171
@batch_stop [:absinthe, :middleware, :batch, :stop]
172+
@batch_timeout [:absinthe, :middleware, :batch, :timeout]
175173
defp emit_start_event(system_time, batch_fun, batch_opts, batch_data) do
176174
id = :erlang.unique_integer()
177175

@@ -200,6 +198,15 @@ defmodule Absinthe.Middleware.Batch do
200198
)
201199
end
202200

201+
defp emit_timeout_event(batch_fun, timeout) do
202+
metadata = %{
203+
fn: inspect(batch_fun),
204+
timeout: timeout
205+
}
206+
207+
:telemetry.execute(@batch_timeout, %{}, metadata)
208+
end
209+
203210
defp call_batch_fun({module, fun}, batch_data) do
204211
call_batch_fun({module, fun, []}, batch_data)
205212
end

test/absinthe/middleware/batch_test.exs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
defmodule Absinthe.Middleware.BatchTest do
22
use Absinthe.Case, async: true
33

4-
import ExUnit.CaptureLog
5-
64
defmodule TimeoutModule do
75
def arbitrary_fn_name(_, _) do
86
:timer.sleep(2000)
@@ -170,20 +168,33 @@ defmodule Absinthe.Middleware.BatchTest do
170168
assert {:ok, %{data: %{"ctx" => "some_value"}}} == Absinthe.run(doc, Schema)
171169
end
172170

173-
test "when batch task timeouts it logs batching options" do
171+
test "when batch task timeouts it emits telemetry event", %{test: test} do
174172
doc = """
175173
{timeout}
176174
"""
177175

178-
assert capture_log(fn ->
179-
pid =
180-
spawn(fn ->
181-
Absinthe.run(doc, Schema)
182-
end)
176+
:ok =
177+
:telemetry.attach(
178+
"#{test}",
179+
[:absinthe, :middleware, :batch, :timeout],
180+
&Absinthe.TestTelemetryHelper.send_to_pid/4,
181+
pid: self()
182+
)
183+
184+
pid =
185+
spawn(fn ->
186+
Absinthe.run(doc, Schema)
187+
end)
183188

184-
wait_for_process_to_exit(pid)
185-
end) =~
186-
"fn: {Absinthe.Middleware.BatchTest.TimeoutModule, :arbitrary_fn_name, %{arbitrary: :data}}"
189+
wait_for_process_to_exit(pid)
190+
191+
assert_receive {:telemetry_event,
192+
{[:absinthe, :middleware, :batch, :timeout], %{},
193+
%{
194+
fn:
195+
"{Absinthe.Middleware.BatchTest.TimeoutModule, :arbitrary_fn_name, %{arbitrary: :data}}",
196+
timeout: 1
197+
}, _}}
187198
end
188199

189200
defp wait_for_process_to_exit(pid) do

0 commit comments

Comments
 (0)