Search code examples
elixirecto

Why does Ecto.Repo process not need `send/receive`?


When making database queries using Ecto we will use something like Users.Repo.get!(id), this of course works, but why do I not need to send/receive to communicate with the Users.Repo process? Why can I just call it as simple as referencing the module and function name?

Users is an OTP Application, where Users.Application has the Users.Repo process loaded as children to the Users.Supervisor process

  ...

  def start(_type, _args) do
    children = [
      Users.Repo,
    ]
    opts = [strategy: :one_for_one, name: Users.Supervisor]
    Supervisor.start_link(children, opts)
  end

Solution

  • Users.Repo gets Ecto.Repo injected with use Ecto.Repo and hence default get/3 implementation is delegated to Ecto.Repo.Queryable.get/3 and then down to adapter.execute/5.

    adapter in turn is already a GenServer and execute/5 is an interface to the process called behind the scene. That abstraction level is required to encapsulate connection pool, timeouts, error handling, etc for you.