sasajuric
Author of Elixir In Action
This is a spin-off from the discussion about the new config proposal. I’m replying to this post by @michalmuskala separately, to avoid noise in that thread.
Currently, it seems to be a bucket for all sorts of things, which includes system configuration. I definitely agree that it’s not a good place for operator configuration.
This sounds vague, could you elaborate what kind of loose coupling do we achieve by e.g. having pubsub: [name: UI.PubSub, adapter: Phoenix.PubSub.PG2] in config?
What is that “everything else”? What’s the criteria for defining a parameter in the config, and not in the code? For example, why should a pubsub name and adapter go to config, but e.g. supervisor name and restart intensity be in the code?
Trending in Discussions
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
New
The obligatory hello world thread!
Who are you and where are you from? :stuck_out_tongue:
New
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
I was working on an Ecto migration and I needed a timestamp. So, for the nth time, I looked up the different data types for timestamps, a...
New
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog
It says that Fly is going all-in on sprites, which is a worry ...
New
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using.
We’re particularly inte...
New
Is there a word for the ~> symbol used in Version strings?
Do you also just call it a Squiggle Arrow™ ?!
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
ICal is a library for interacting with iCalendar data. It parses iCalendars into typed Elixir structs via ICal.from_ics, and can prepare ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #phoenix_html
- #elixirconf-us
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Qqwy
A thing I’d like to mention here since it definitely does not belong in the proposal-topic, although it might also be a bit tangential to your posts, @sasajuric (but I first started thinking about this during reading your blog article) :
It actually strikes me as weird that there are so many configuration settings that will require an os-application to completely restart. To be perfectly honest, even if parts of the os-application (some of the beam-applications) require configuration to happen at compile-time, shouldn’t we find a way to re-compile them at runtime instead?
sasajuric
The thing is that app env is a mutable storage, but very often values are retrieved only once. You don’t need to restart the entire app to reapply the change setting, but you do need to restart the processes which read the setting.
To make some property truly dynamic, you should avoid “caching” it into a variable. This will in some cases not be enough by itself, and might require much more work. For example, to make an http port dynamically configurable, you need to poll for app env change, then start another server and drain the old one. It’s probably not worth the hassle, and so I’d just suggest proclaiming the http port constant. But if it’s a constant, then why keep it in a mutable store which gives you an illusion of reconfigurability, and which might even be accidentally changed, which could lead to some strange consequences?
That’s why I think that in many cases app env is not the good place to keep settings to begin with. A lot of stuff ends up there just because app env “feels” like the place to keep some parameters. If we keep in mind that app env is just another storage, just like OS env, or external file, or a database, and remember the properties of app env (global, mutable, in-memory), then I think it becomes clearer that it’s not a good place to store every single piece of data, especially not the data which never changes during the system lifetime.
bitwalker
I think a great deal of the abuse of the application env occurs because it is simply easy to do so. It is more difficult to think about how to make your library or application configurable by feeding in parameters to a top-level supervisor or something, than it is to just stuff anything configurable into
config.exsand useApplication.get_env/3. As long as the easier path is available, there will always be people who take it. Erlang didn’t have quite as much of an issue with this, because it was more of a pain to use the application env for configuration than it was to configure via parameters.I think a related issue is compile-time configuration. Some of the examples José mentions need configuration inputs at compile-time, and there is no other means to provide them except
config.exs, since Mix evaluates it during compilation. Had Mix gone the route of Erlang in regards to application env, the whole discussion would be moot, sinceconfig.exswould be limited to runtime configuration. Since it did not, we also have the problem whereconfig.exshas become the catch-all for anything configurable. People are usingSystem.cmd/3to get a git shorthash inconfig.exs, rather than doing something like-Dcommit_hash=$(git describe --tags --long)as a flag to the compiler, which is how such things are typically handled in just about every other language I’ve worked with. That isn’t suitable for everything though, and is unwieldy for repeated use. This is definitely a place whereconfig.exseases a lot of pain - compile-time parameters and global defaults.I was hoping that by treating
config.exsas a runtime config, and havingmix.exshandle defining what to include or not include at compile-time, we could get the best of both worlds. It doesn’t really solve the issue of how to prevent people from abusing the app env, but I’m not sure that is something we can really fix at this point, about the only time you could make that kind of change is with a theoretical Elixir 2.0, but its not clear how you could do that without making configuration more inconvenient in general. It seems like a bit of a catch-22 to me.sasajuric
Yeah, I agree with this 100%
I think it could be improved if onboarding resources promoted plain data passing, and generators such as
mix phx.newpreferredinit/2over app env.Some other minor additions, such as the ability to compute a value before compilation (so e.g. mix.env) and fetch it in a module could also help with the trickery which is
System.cmdin mix scripts.So in general I think that some education, pushes from popular generators, and a couple of minor additions from the language and mix could at least guide us all in a better direction.
jeremyjh
I think the
config.exskind of makes sense for configuring modules/applications provided by your dependencies. I may not have any application code that should be the particular owner for those parameters. It may also not make sense for me to manage a server provided by the dependency, just so it can be configurable. People would end up implementing these servers wrong and make their library single-threaded when it has no other reason to be (this already happens sometimes).OvermindDL1
These are exactly my complaints, there needs to be a registrateable callback for these (send a message to a process or something on change)…
Yeah, there are a LOT of third-party libraries (and some first-party ones too *coughs*) that put things in the config that should be passed in via supervisor arguments or so…
Indeed.
mix.exsshould be build-time configuration, arguments should be boot-time, and the application environment should be run-time. If the application environment was not accessible at build time at all then that would go a long way to help (the theoretical Elixir 2.0 though, but perhaps warnings could help for now).Precisely, everything should be in such an ‘init’, though this would be a great place to fit the JVM style static/overrideable configs into as well.
Except why can’t they specify their own default run-time configurations instead of having to put it in your own config (many third-party libs don’t have good defaults in the code), or be able to inherit it from a dependency that depends on another dependency without you (again) copying it into your own config. The java model handles all this well.
Qqwy
I guess they can and should already do so now; this is more a flaw in how those libraries have been written than in the current way we do configuration, I think.
As for changing configuration on the fly, I agree with @OvermindDL1 and @sasajuric that probably the only feasible way would be to call a ‘reconfigure’ function when you want to change something, rather than altering the Application environment (the ‘ground’) under any process’ feet.
@bitwalker What about adding an
:extra_compile_argslist tomix.exsI completely agree that usingSystem.cmdin the configuration file is very odd.sasajuric
This still seems vague and leaves me puzzled. Why should I set a pubsub name in config.exs but provide e.g.
Registryname in my code. Both pieces of data are parameters to my dependencies (i.e. to the code which is not a part of the project).jeremyjh
The difference is you are managing the
Registryserver, it isn’t started automatically just by including the application in your dependencies. While it makes sense to pass all the parameters to servers you control, my point was just that servers are not the answer to all configuration problems. It would be a worse problem if we forced library authors to write servers to collect and hold compile-time config, which is I think where your proposal leads us. Unless I misunderstand something.I’m sure you won’t find anyone defending that. Good defaults and usability are important regardless of how we collect configuration data. The JVM system has its failure modes as well, I once had to debug a production system I inherited that had the same properties deployed in three different files as well as the launch command. That isn’t the fault of the JVM, but of poor development and operations practices. Your complaint about library defaults seems similar.
edit: pubsub is actually a bad example for me; I thought it was started separately as its a separate library but I looked into it and its started by the Phoenix endpoint which is started ultimately by the user’s endpoint module in Application.start(), so config could be supplied either to that child or in the Endpoint
usemacro I believe.sasajuric
Ah, I see what you mean now.
AFAIK, the pubsub server is also started in my supervision tree. It couldn’t be started otherwise, as it’s ultimately obtained from
init/2of my endpoint, which is also in my supervision tree.In other words, this is not automatically started when the Phoenix app is starting, and hence that’s not a reason to require placing pubsub name (which AFAICT is not even a registered name, but just some piece of data use internally by Phoenix machinery) into config script or app env. In fact, for my blog, this data is not in app config.
Not sure which proposal you refer to. I’m certainly not suggesting that there’s one-size-fits-all approach to providing data. That’s certainly not app config, and those are also not processes, nor app env, nor any other mechanism of passing data.