Plug's init function not called at compile time in a Phoenix router

Hi all,

I am trying to retrieve some Plug options at compile time in the init/1 function implementation since I read here and there that Plugs’ init functions were called at compile time. More precisely, I want to retrieve the list of issuers here (that’s a mandatory parameter) at compile-time, for use by a mix task.

However I’ve just noticed that init/1 is called at runtime, by removing this issuer parameter (the app still compiles).

Is that something I misconfigured or misunderstood, or is that normal?

As a side question, how would you retrieve this :issuer values from such a router module to be used by mix task? Maybe using Code.eval_file/2?

Phoenix generates config for MIX_ENV=dev like:

config :phoenix, :plug_init_mode, :runtime

which causes the behavior you’re seeing.

iirc, by default in recent Phoenix releases, init/1 is called at runtime in development and compile time in production.

For your second question, I wouldn’t configure the string literal for your issuer, I’d either have that as an ENV_VAR, or app config or compile it into a Config module that you then use in your plug and your mix task. For example:

  pipeline :one_factor do
    plug Plugoid,
      issuer: Plugoid.Config.get(:gigalixir),
      client_id: "client1",
      ...
  end

And

defmodule Plugoid.Config do
  def get(:gigalixir) do
    "https://repentant-brief-fishingcat.gigalixirapp.com"
  end
end

Thanks both, that was it!

To solve that specific problem or is there another reason for that? Given that the issuer is not a secret.

Because you said you wanted to use the issuer information in both the plug and a mix task. Which to me suggests extracting it to an ENV_VAR, app config or common config module. I think thats much cleaner than Code.eval_file/2