Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/new config system (improved) #1637

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

mikkoi
Copy link

@mikkoi mikkoi commented Feb 2, 2022

No description provided.

@mikkoi mikkoi force-pushed the feature/new-config-system-2 branch 2 times, most recently from d9901f7 to dfd9ced Compare February 2, 2022 21:27
@mikkoi mikkoi mentioned this pull request Feb 2, 2022
Copy link
Member

@xsawyerx xsawyerx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

This makes sense, but it also suffers from the assumption that all configurations are files, so while it's more abstract it's - and I'm sorry to say this - not abstract enough.

The naming for Role::Config and Role::ConfigReader and ConfigReader gave me a bit of confusion trying to grok this.

I'm also missing the role HasLocation. I don't see where it went. Is it no longer necessary because the location is sent through the App to Role::Config?

I think this warrants further discussion because I don't think we should merge this when it's halfway between being too rigid and not being flexible enough. Once you could correct whatever I got wrong, I'm happy to propose an improved structure.

@@ -84,9 +91,11 @@ has global_triggers => (
},
};

no warnings 'once'; # Disable: Name "Dancer2::runner" used only once: possible typo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worthwhile exploring this warning.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seconded.

lib/Dancer2/Core/Role/Config.pm Outdated Show resolved Hide resolved
lib/Dancer2/Core/Role/Config.pm Outdated Show resolved Hide resolved
lib/Dancer2/Core/Role/Config.pm Outdated Show resolved Hide resolved
to manage the Dancer2 configuration.

It is now possible for user to control which B<ConfigReader>
class to use to create the config.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Users can control which B class to use when creating the config."

Same comment as above.

lib/Dancer2/Core/Role/Config.pm Outdated Show resolved Hide resolved
lib/Dancer2/Core/Role/Config.pm Outdated Show resolved Hide resolved
my $runner_config = defined $Dancer2::runner
? Dancer2->runner->config
: {};
use warnings 'once';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be easier to write:

        my $runner_config;
        {
            no warnings 'once';
            $runner_config = defined $Dancer2::runner
                           ? Dancer2->runner->config
                           : {};
        }

I would still want to know if we could avoid that warning.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reformatted.

lib/Dancer2/ConfigReader/File/Simple.pm Outdated Show resolved Hide resolved
lib/Dancer2/ConfigReader/File/Simple.pm Outdated Show resolved Hide resolved
@mikkoi
Copy link
Author

mikkoi commented Feb 4, 2022

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.

@xsawyerx
Copy link
Member

xsawyerx commented Feb 5, 2022

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...)

@mikkoi
Copy link
Author

mikkoi commented Feb 6, 2022

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.

@xsawyerx
Copy link
Member

xsawyerx commented Feb 7, 2022

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.

@mikkoi
Copy link
Author

mikkoi commented Feb 9, 2022

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.

@xsawyerx
Copy link
Member

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.

@cromedome
Copy link
Contributor

cromedome commented Feb 15, 2022

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.

@mikkoi mikkoi force-pushed the feature/new-config-system-2 branch from dfd9ced to 3eb359f Compare March 27, 2022 14:55
@mikkoi
Copy link
Author

mikkoi commented Mar 27, 2022

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

@mikkoi
Copy link
Author

mikkoi commented Mar 27, 2022

@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.

@xsawyerx
Copy link
Member

xsawyerx commented May 3, 2022

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.)

@mikkoi mikkoi force-pushed the feature/new-config-system-2 branch from 3eb359f to c99b4b4 Compare May 8, 2022 18:25
@mikkoi
Copy link
Author

mikkoi commented May 8, 2022

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
Copy link
Author

mikkoi commented May 9, 2022

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.

Role::Config is the configuration part of an object
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Remove everything that has to do with loading config
from files or elsewhere.

Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Create Dancer2::Core::Role::ConfigReader and Dancer2::ConfigReader::File::Simple.

Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Also specify lazy => 1.

Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
* Remove previously commented out code
* Remove 'use Data::Dumper'

Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
Signed-off-by: Mikko Johannes Koivunalho <[email protected]>
@mikkoi
Copy link
Author

mikkoi commented Sep 25, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants