Calling Ecto.Repo in a telemetry handler results in DbConnection.ConnectionError

Hey team,

In my Phoenix app, I’ve attached a telemetry handler to Phoenix router events like so:

:ok =
      :telemetry.attach_many(
        "analytics-request-tracking",
        [
          [:phoenix, :router_dispatch, :stop],
          [:phoenix, :router_dispatch, :exception]
        ],
        &MyApp.Analytics.handle_event/4,
        nil
      )

Inside my telemetry handler, I make a database query like so:

def handle_event(_, _ ,_) do
  MyApp.Repo.query("select 1")
end

This results in the telemetry handler crashing:

[info] pid=<0.1275.0> [info] Postgrex.Protocol (#PID<0.1275.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.2685.0> exited

Interestingly, the pid inside the controller handler and the telemetry handler is the same. So both are run in the same process. My assumption is that when the response is sent to the client, the database connection’s checkout is ended? So then my telemetry handler can no longer access it?

What’s advised in this situation?

Thanks,
Anthony

Telemetry execution is executed synchronously, so ideally you shouldn’t call DB query which induce latency in that process (GitHub - beam-telemetry/telemetry: Dynamic dispatching library for metrics and instrumentations.).

Alternatively, you may spawn supervised task / delegate your DB query into another process/worker if you doesn’t need the result of DB query immediately.

Not sure why you get DB disconnected though.

1 Like