Determine if I am in iex

I have a GenServer to do some work and would like to render a ProgressBar but only if I am in iex so it does not log progress bars when it’s running automated in production.

Maybe I can check for Application.get_env(:elixir, :ansi_enabled) but I don’t know if that is reliable or if there is a better way.

2 Likes

Maybe you should make the progress bar code run only in :dev environment and nowhere else? Or are you also planning getting inside your :prod code through iex?

I’d be temped to move the progress bar rendering into an entirely different process. The minimal impact on the GenServer would be to decide whether or not to send progress message to a registered “listener”.

In IEx starting up the listener process then registers with the GenServer to get (and render) the progress.

Kernel.send/2 (i.e. casting) messages to a non-existent process has no ill effect on the sending process - though it would still be nice if the listener unregistered before terminating and there was a way to silence the GenServer so the BEAM isn’t burdened with unproductive messages.

You may also be able to start the listener process automatically in the .iex.exs file at the root of your project.

2 Likes

Application.get_env(:elixir, :ansi_enabled) is good way to check whether displaying a progress bar is appropriate.
Take a look at this piece of documentation in the Elixir code relating to :ansi_enabled:

:ansi_enabled in the :elixir application […] is by
default false unless Elixir can detect during startup that
both stdout and stderr are terminals.
elixir/lib/elixir/lib/io/ansi.ex at main · elixir-lang/elixir · GitHub

1 Like

https://hexdocs.pm/iex/IEx.html#started?/0

3 Likes

One simple way to do this is add the following to your .iex.exs

Application.put_env(:my_app, :iex_started, true)

iex loads the .iex which would set up your config which can the be checked in your app.

5 Likes

First off: wow, so many great and insightful answers! Love this community :heart:

I did not mention it but I already extracted the Progress Bar rendering to its own GenServer. I like the idea of doing the setup in .iex.exs to avoid conditionals in the actual application.

I selected the answer by @fuelen as solution because it answers the question in the thread title.

However, that’s not what I will end up using. I thought about possible use cases again and figured that the progress should render as well when run via mix command. For rendering in both IEx and mix, my initial suggestion Application.get_env(:elixir, :ansi_enabled) seems to work perfectly.

To see it all in context, here’s my implementation using GenServer: https://gist.github.com/eteubert/8d32b404bf0d9b4f4a1482e907619911

Excerpt:

defp render(current, total) do
  should_render? && ProgressBar.render(current, total)
end

defp should_render? do
  Application.get_env(:elixir, :ansi_enabled)
end
1 Like