diff --git a/guides/telemetry.md b/guides/telemetry.md index a9c607b878..efd509b7ea 100644 --- a/guides/telemetry.md +++ b/guides/telemetry.md @@ -89,3 +89,13 @@ Instead, you can add the `:opentelemetry_process_propagator` package to your dependencies, which has a `Task.async/1` wrapper that will attach the context automatically. If the package is installed, the middleware will use it in place of the default `Task.async/1`. + +Alternatively, you can configure the `Task` implementation to use: + +```elixir +config :absinthe, task_module: MyTaskModule +``` + +This is a compile-time option, so it cannot be configured in `runtime.exs`. +Instead, place it in `config.exs` or build-specific configs (`dev.exs`, +`prod.exs`, etc.). The provided module must support the `async/1` function. diff --git a/lib/absinthe/middleware/async.ex b/lib/absinthe/middleware/async.ex index 52bdaccdb1..5692a3b4f6 100644 --- a/lib/absinthe/middleware/async.ex +++ b/lib/absinthe/middleware/async.ex @@ -38,6 +38,8 @@ defmodule Absinthe.Middleware.Async do @behaviour Absinthe.Middleware @behaviour Absinthe.Plugin + import Absinthe.Utils, only: [async: 1] + # A function has handed resolution off to this middleware. The first argument # is the current resolution struct. The second argument is the function to # execute asynchronously, and opts we'll want to use when it is time to await @@ -110,13 +112,4 @@ defmodule Absinthe.Middleware.Async do pipeline end end - - # Optionally use `async/1` function from `opentelemetry_process_propagator` if available - if Code.ensure_loaded?(OpentelemetryProcessPropagator.Task) do - @spec async((-> any)) :: Task.t() - defdelegate async(fun), to: OpentelemetryProcessPropagator.Task - else - @spec async((-> any)) :: Task.t() - defdelegate async(fun), to: Task - end end diff --git a/lib/absinthe/middleware/batch.ex b/lib/absinthe/middleware/batch.ex index 4dc25ab159..98fd161d1e 100644 --- a/lib/absinthe/middleware/batch.ex +++ b/lib/absinthe/middleware/batch.ex @@ -62,6 +62,8 @@ defmodule Absinthe.Middleware.Batch do require Logger + import Absinthe.Utils, only: [async: 1] + @typedoc """ The function to be called with the aggregate batch information. @@ -226,13 +228,4 @@ defmodule Absinthe.Middleware.Batch do pipeline end end - - # Optionally use `async/1` function from `opentelemetry_process_propagator` if available - if Code.ensure_loaded?(OpentelemetryProcessPropagator.Task) do - @spec async((-> any)) :: Task.t() - defdelegate async(fun), to: OpentelemetryProcessPropagator.Task - else - @spec async((-> any)) :: Task.t() - defdelegate async(fun), to: Task - end end diff --git a/lib/absinthe/utils.ex b/lib/absinthe/utils.ex index eaa562566d..843623ad0e 100644 --- a/lib/absinthe/utils.ex +++ b/lib/absinthe/utils.ex @@ -151,4 +151,19 @@ defmodule Absinthe.Utils do #{types ++ directives} """ end + + task_module = Application.compile_env(:absinthe, :task_module) + + @spec async((-> any)) :: Task.t() + cond do + is_atom(task_module) and task_module != nil -> + def async(fun), do: unquote(task_module).async(fun) + + # Optionally use `async/1` function from `opentelemetry_process_propagator` if available + Code.ensure_loaded?(OpentelemetryProcessPropagator.Task) -> + defdelegate async(fun), to: OpentelemetryProcessPropagator.Task + + true -> + defdelegate async(fun), to: Task + end end