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

Jskalc
Hi everyone! Recently I was thinking a lot about the way HEEX renders lists. People are generally surprised about huge payloads being sen...
New
andypearson
Hey all, I have been working on some performance improvements for the Phoenix application I work on. As part of this, through trial and...
New
marcandre
I notice that most events have bindings (e.g. phx-keyup) but not the input event. The input event is the preferred way to interact with ...
New
AHBruns
So, LiveView 0.20 brought an async processing API which is a thin wrapper around tasks. It’s a very nice convenience, but the main thing ...
New
cevado
IEx is a very powerfull shell and it would be awesome to have all this power integrated inside a code editor. Clojure enables something l...
New
sevensidedmarble
Hello all, Apologies if this has been proposed before I guess, but I have a very simple one: With the increasing importance of LV, I th...
New
spicychickensauce
I’ve previously explored what is possible today with hacks to implement view transitions in our apps: I have since created a fork to im...
New
7rans
I implemented Access behavior for a struct today. Pseudo-code… defmodule MyStruct do defstruct data: %{} @behaviour Access # ... ...
New
dimitarvp
To @jonatanklosko and @the-mikedavis: I see that there is a Rust crate at crates.io: Rust Package Registry but it is pointing at https:/...
New
alaadahmed
Hi folks, I tried Phoenix 1.7 and it is awesome, but I have small suggestion, which in my opinion will organize files in a better way. ...
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
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement