-
Notifications
You must be signed in to change notification settings - Fork 409
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
Add structured config compilation #8098
Conversation
d8b875e
to
3eff4c4
Compare
Structured config values are Python objects from environment variables or (future) TOML config files. The compilation re- assembles the objects into ConfigOp ASTs and use the static evaluation mechanism to generate verified config values. As a side-effect, such config sources now support specifying EdgeQL values directly in a double-braces, for example: env GEL_SERVER_CONFIG_cfg::session_idle_timeout \ = "{{<duration>'5s' * 2}}" Technically, this allows setting nested config objects with INSERT statements too.
3eff4c4
to
12d3a25
Compare
Can you give an example of how that might look? |
This works:
It's compiled into such AST:
Then it's statically evaluated into:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good broadly, but I have some concerns we need to figure out about the config object situtation
) -> dict[str, immutables.Map[str, config.SettingValue]]: | ||
# XXX: only config in the stdlib is supported currently, so the only | ||
# key allowed in objects is "cfg::Config". API for future compatibility | ||
if list(objects) != ["cfg::Config"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it arguably be cfg::AbstractConfig
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes? Though, it's a bit weird for the user to write [cfg::AbstractConfig]
in the TOML config file.
Fwiw using cfg::Config
here is following this line which was added before we even had cfg::AbstractConfig
and never got updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, ok
tests/test_server_compiler.py
Outdated
def _test_compile_structured_config( | ||
self, | ||
values: dict[str, Any], | ||
*, | ||
source: str = "config file", | ||
**expected: Any, | ||
) -> dict[str, config.SettingValue]: | ||
result = self.compiler.compile_structured_config( | ||
{"cfg::Config": values}, source=source | ||
) | ||
rv = dict(result["cfg::Config"]) | ||
for name, setting in rv.items(): | ||
self.assertEqual(setting.name, name) | ||
self.assertEqual(setting.scope, config.ConfigScope.INSTANCE) | ||
self.assertEqual(setting.source, source) | ||
self.assertDictEqual({k: v.value for k, v in rv.items()}, expected) | ||
return rv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get an end-to-end test, also?
One thing I am concerned about is how INSERTed objects specified via structured config will interact with objects inserted manually via CONFIGURE INSTANCE INSERT ...
.
The best option is for the sets of objects to get merged. I spent about a day trying to make that work, and came to the conclusion that it would probably take me closer to a week, and would be pretty hairy. This is why I introduced EDGEDB_MAGIC_SMTP_CONFIG
, so we wouldn't need to handle it.
If manually inserted objects just fully override, that is probably acceptable behavior (though it wouldn't work for our SMTP config case, so we would still need EDGEDB_MAGIC_SMTP_CONFIG), but I think it will take a little care to make that work properly also. (If you INSERT an object and then RESET it away, probably the structured config one should come back? But I think as implemented it won't quite work.)
Anyway, I don't think this really blocks us, but I think we might need to disable object config for now, and stick with EDGEDB_MAGIC_SMTP_CONFIG for the case we need. (We should probably use the structured parser for EDGEDB_MAGIC_SMTP_CONFIG though!)
I think getting objects to work well enough to cover that case for us will be a decent amount of extra work, and not a priority yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I also left 2 similar questions in the previous PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a switch to turn configure ... insert
off for now. End-to-end tests for non-insert configs are covered by the env var static config tests now; the upcoming TOML config file PR will include more e2e tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably use the structured parser for EDGEDB_MAGIC_SMTP_CONFIG
Fixed!
tenant=tenant, | ||
use_monitor_fs=args.reload_config_files in [ | ||
srvargs.ReloadTrigger.Default, | ||
srvargs.ReloadTrigger.FileSystemEvent, | ||
], | ||
net_worker_mode=args.net_worker_mode, | ||
) | ||
magic_smtp = os.getenv('EDGEDB_MAGIC_SMTP_CONFIG') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you do a manual test of this, since apparently I half-assed it and didn't write one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, manually tested ✅
Structured config values are Python objects from environment variables or (future) TOML config files. The compilation re- assembles the objects into
ConfigOp
ASTs and uses the static evaluation mechanism to generate verified config values.This supersedes #8059 as a less-hacky way to validate config values.
As a side-effect, such config sources now support specifying EdgeQL values directly in a double-braces, for example:
Or even simpler:
(because the typecast is included by default)
This allows setting nested config objects with INSERT statements too:
Sample: