c4710n

c4710n

A proposal for improving the workflow of `iex -S mix phx.server`

This is an idea for improving the workflow of iex -S mix phx.server

The Problem and The Solution in use

When running multiple Phoenix endpoints in an environment where you only have access to single port, we often:

  • use a proxy like main_proxy.
  • set server: false for all the endpoints.

But, after :server option is set to false, the endpoint watchers won’t start anymore - that’s the problem.

I have noticed :force_watchers option and the original PR.

Indeed, it works. But I think there is still room for improvement.

A Potential Problem

Let’s imagine a case first:

  • I have an umbrella project contains multiple Phoenix endpoints.
  • I configure main_proxy for these Phoenix endpoints.
  • I set server: false for these endpoints.
  • I set force_watchers: true for these endpoints.

Now, I want to enter the dev environment:

$ iex -S mix phx.server

Everything works fine.

But, sometimes, I want to enter the dev environment without starting watchers (for example, connect to an existing node which already starts watchers):

$ iex -S mix --sname bob

However, as it turns out, the watchers are still started. (After all, we used the :force_watchers option.)

In this case, :force_watchers can’t help, and it brings conflicts on the running watchers. (For example, you are running two esbuild instances for the same assets, that’s not what you want, generally.)

How to solve this problem?

An Idea

I have a roughly formed idea:

  • seperate the functionalities of endpoints into two:
    • web server
    • watchers
  • iex -S mix phx.server controls web server and watchers at the same time:
    • That is because the underlying implementation is Application.get_env(:phoenix, :serve_endpoints).
    • It concerns endpoints. And, as said above, endpoints have two functionalities - web server and watchers.
  • :server option controls the web server
  • :force_watchers option controls the watchers

A simple change on the code here:

# unchanged
defp server?(conf) when is_list(conf) do
  Keyword.get_lazy(conf, :server, fn ->
    Application.get_env(:phoenix, :serve_endpoints, false)
  end)
end

# changed for this idea
defp watcher?(conf) do
  Keyword.get_lazy(conf, :force_watchers, fn ->
    Application.get_env(:phoenix, :serve_endpoints, false)
  end)
end

defp watcher_children(_mod, conf) do
  if watcher?(conf) do
    Enum.map(conf[:watchers], &{Phoenix.Endpoint.Watcher, &1})
  else
    []
  end
end

Use Cases

Let’s take another look and see if this idea can cover all general use cases.

Enable web server and watchers

iex -S mix phx.server

Cases:

  • normal Phoenix projects in dev environment

Enable web server only

Set server: true.

Cases:

  • normal Phoenix projects in prod environment

Enable watchers only

  • iex -S mix phx.server
  • Set server: false

Cases:

  • umbrella projects contains multiple proxied phoenix endpoints in dev environment

Disable web server and watchers

  • do nothing

Cases:

  • umbrella projects contains multiple proxied phoenix endpoints in prod environment
  • just want to run iex -S mix

Last

Personally, I think this is a good proposal, which expands the applicability of iex -S mix phx.server. :wink:

That’s what I wanted to say. Thank you very much for reading. All feedback is welcome.

If you all like this proposal, I will create a pull request.

Most Liked

Ankhers

Ankhers

Just to add. Generally speaking you should not be using mix in production. It is really meant for development. In production you should probably create and deploy a release. That can be started however you want.

josevalim

josevalim

Creator of Elixir

Plus doing so could potentially be a breaking change. My suggestion would be for you to create additional mix tasks. You don’t have to use mix phx.server, you can roll your own with your own defaults.

chrismccord

chrismccord

Creator of Phoenix

I’m not convinced this is a feature or change we need. Thanks!

Where Next?

Popular in Proposals: Ideas Top

Rubas
Current Challenge When testing LiveViews that use assign_async, we can’t really operate on the async data. render_async(view) waits f...
New
GregPhx
Greetings Everyone!!! A little bit of my background so it could be easier to understand where my comments are coming from, and to take t...
New
cevado
I was reading the EEP-79, and thinking about the poor record support in Elixir(i’ve tried to discuss about that in the forum before). I s...
New
andreamancuso
Hey folks, This might sound niche, but I think it’s worth bringing up - especially given Phoenix’s reputation for being lightweight, por...
New
manhvu
In a large repo, working with module need to add alias too much is quite annoyed and not good for organizing code. I think better add su...
New
Astolfo
When generating a release with phx.gen.release --docker a debian version is used by default to avoid “DNS issues” on Alpine. It seems li...
New
kccarter
This is likely a feature request unless we’re overlooking something, but it would be a nice improvement to the developer experience if th...
New
zachdaniel
Something we do in various Ash packages is provide routes that the user forwards to in their own application. This is because we are deri...
New
lemaster
Currently we have stream_insert and stream that can either add new items to a stream or update existing items if they are already present...
New
nunobernardes99
On 1.8+, when we generate an authentication system with mix phx.gen.auth we can make use of magic link login which is amazing and a great...
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement