Dancer2 icon indicating copy to clipboard operation
Dancer2 copied to clipboard

Feature/new config system (improved)

Open mikkoi opened this issue 2 years ago • 13 comments

mikkoi avatar Feb 02 '22 21:02 mikkoi

If I understand correctly, the way you see it is:

The App now uses Role::Config
The role Role::Config has config_readers and config_files
Each of the Config Reader classes consumes Role::ConfigReader
Each of these classes also has its own config_files which they merge together
The Role::Config will then merge these "merged" config files into its own config_files and its configuration itself, which then the App is able to use

Did I understand this right?

Yes, precisely. I made a conscious design decision to keep the changes to a minimum and maintain complete compatibility. That is the reason why config_files is kept even though it doesn't make much sense in this new setup. Instead of config_files we should have something like config_origin. The same reason why the new solution isn't "abstract enough".

Again the same applies to HasLocation. Location is deduced once and then passed on to the config readers. Just like environment name.

mikkoi avatar Feb 04 '22 22:02 mikkoi

I think calculating location and environment only once and transferring it onwards is a good call. I like that.

I think the usage of roles here might be too much. How about:

  • Dancer2::ConfigReader as an object holding configuration information.
  • It has config_readers who all consume the Role::ConfigReader role.
  • They can each have whatever attributes they want. The ConfigReader::File::Simple (or Config::Type::File::Simple) will have config_files as an attribute since it reads from [simple] configuration files. A different configuration might have elastic_params because it uses ElasticSearch to include configurations, for example.
  • The App would create an instance of the ConfigReader object with the location and environment.
  • The ConfigReader will determine which configuration reader it should use and instantiate them and use them to collect the configuration.

Two things left in mind:

  • If you edit the value of the configuration readers to use using the set keyword, will we be able to use this by the time ConfigReader tries to instantiate configuration readers?
  • We shouldn't (at least for now) support recursive levels of configuration readers, like "read the config file, then the config file contains other configuration readers, use them, etc." until we research how others handle this problem. (Thought: We do support local config files - so theoretically, we could use that second-level configuration part to hook into reading from non-configuration files...)

xsawyerx avatar Feb 05 '22 16:02 xsawyerx

If we ditch config_files attribute, we create a non-compatible change.

The name is bad but I like the idea that the Config object would actually know where the configs come from, at least on a surface level (list of files or sources).

If you edit the value of the configuration readers to use using the set keyword, will we be able to use this by the time ConfigReader tries to instantiate configuration readers?

I don't think its possible. For the same reason I couldn't use hooks. It creates a dependency on user code before App is ready - and config should be read and ready before App is accessible for users.

We shouldn't (at least for now) support recursive levels of configuration readers, like "read the config file, then the config file contains other configuration readers, use them, etc." until we research how others handle this problem. (Thought: We do support local config files - so theoretically, we could use that second-level configuration part to hook into reading from non-configuration files...)

Agree. Too many moving parts for the moment.

mikkoi avatar Feb 06 '22 11:02 mikkoi

If we ditch config_files attribute, we create a non-compatible change.

Incompatible with what?

The name is bad but I like the idea that the Config object would actually know where the configs come from, at least on a surface level (list of files or sources).

Sorry, I don't understand your comment here.

xsawyerx avatar Feb 07 '22 13:02 xsawyerx

Attribute config_files is part of the public interface, isn't it? If it isn't, then of course, it's not a compatibility issue.

Just thinking that I like the idea that the config readers maintain a list of files or sources where the config is read from.

mikkoi avatar Feb 09 '22 21:02 mikkoi

Attribute config_files is part of the public interface, isn't it? If it isn't, then of course, it's not a compatibility issue.

I can't imagine this being used for anything. The Config Reader is a role composed into classes. If someone is using it, that's not in a way that we should worry about officially supporting.

Just thinking that I like the idea that the config readers maintain a list of files or sources where the config is read from.

It makes sense if the specific sense of configuration as files, but in the abstract sense of configuration as values by keys, files are a secondary - and more important, optional - concept.

xsawyerx avatar Feb 10 '22 15:02 xsawyerx

Attribute config_files is part of the public interface, isn't it? If it isn't, then of course, it's not a compatibility issue.

The only thing someone could be using this for, I'd think, is logging the contents of what's there (and that is already happening on app startup). Maybe some devs got clever with the contents. We could remove it and see who complains, or for non-file based configs (etcd, Vault, wherever else you might pull config from) we could put a one-line description in about where the config came from. Personally, I'd rather remove it, make a developer release, document the removal, and see who complains.

Just thinking that I like the idea that the config readers maintain a list of files or sources where the config is read from.

As do I. I am not sure what I'd do with that info yet, but having it is intriguing. If only for some debugging purposes down the road.

cromedome avatar Feb 15 '22 01:02 cromedome

I have changed all the small things and I removed the attributeDancer2::Core::Role::Config::config_files.

mikkoi avatar Mar 27 '22 14:03 mikkoi

@xsawyerx Did you really mean we should make so big change? To abandon App having Config as a role, and instead instantiate ConfigReader? It means we would need to implement the functionality to access configuration content in App and in ConfigReader.

Or else, we could redesign the whole thing so that Config and ConfigReader have nothing to do with each other, except that configuration is something that ConfigReader produces and then gives/assigns to Config.

It seems like a very big change.

mikkoi avatar Mar 27 '22 15:03 mikkoi

I do think we need to make such a big change and I don't think this big change is this "big." Of course, I could be wrong about that. (But it would still be the right thing to do.)

xsawyerx avatar May 03 '22 17:05 xsawyerx

To be on the safe side, I rebased the branch from master. So I had to force push.

The new commits are:

The main changes are: There is now Role::HasConfig which has those parts of the old Role::Config which were about accessing and changing the config. There is now Role::HasEnvironment to isolate the environment deducing code (we get env name from ENV vars, etc.) ConfigReader is instantiated as an attribute to Dancer::Core::App.

mikkoi avatar May 08 '22 18:05 mikkoi

The test t/issues/gh-634.t is failing because it uses config_location from Role::Config. The test needs to be thought out again.

mikkoi avatar May 09 '22 20:05 mikkoi

The tests now run. @xsawyerx Do we need more fine tuning before merging?

mikkoi avatar Sep 25 '22 20:09 mikkoi