[PEAK] Unifying configuration
Phillip J. Eby
pje at telecommunity.com
Fri Dec 19 17:27:02 EST 2003
At 11:12 PM 12/19/03 +0200, alexander smishlajev wrote:
>Phillip J. Eby wrote, at 19.12.2003 21:12:
>
>>With this addition, a lot of the need for using ZConfig syntax in .inis
>>will go away, since you'll be able to very cleanly create even complex
>>objects in an expression.
>
>but this will not eliminate the issue that caused us to switch from .ini
>to ZConfig: to read a component settings from .ini file we must know that
>our application contains that component. with ZConfig, the list of
>included components is naturally created from component sections.
Ty and I have just worked out a solution for this, a concept to allow
"plugins" for arbitrary components. These will allow a component to do
something like:
myPlugins = binding.Obtain(
config.PluginsFor('someComponent.plugins'), uponAssembly=True
)
'myPlugins' would then end up as either a dictionary or list or some other
structure containing all of the plugins defined in an .ini like so:
[someComponent.plugins]
fooPlugin = ...
something = ...
'config.PluginsFor' will take keyword arguments to control how the
namespace is searched/sorted to obtain the plugins.
The plugin objects will of course then be attached to their owner, so they
will then be able to do any 'uponAssembly' actions like registering with
services like the reactor or the logging service or the performance timer
system, etc.
>pure ZConfig is a one-in-a-whole thing. if there is an error (either
>syntax error, or environment error, like missing directory, preventing an
>instantiation of at least one component) the application does not start at
>all, even if 90% of it are ok. if we need to change a setting for one
>component, we have to restart the whole application.
I would note that this is actually a good thing for end-user configuration,
because it should prevent somebody breaking something and not noticing.
>by keeping the text of ZConfig inclusions and parsing them at the time
>they are accessed we could isolate single component problems without
>disturbing other components.
Note that it's possible even now to load separate ZConfig files from in an
.ini, it's just rather tedious, especially with all the importString()'s
required to do the job.
>if ZConfig inclusions are kept as a text and parsed upon access, we could
>also implement a dynamic reconfiguration of some components by utilizing
>ZConfig '%include' feature: included file is read at the time of ZConfig parse.
I think that we could address this use case by having an easy way to load a
ZConfig file from an .ini file (i.e., not using %include). When combined
with the proposed 'PluginsFor()' mechanism, I think you could do something
like:
[ourapp.plugins]
foo = config.loadZConfig(targetObj, "schemaX", "fileY")
bar = config.loadZConfig(targetObj, "schemaX", "fileZ")
...
The messy part above is that the schema would be loaded multiple
times. So, we may want to have a ZConfigSchemaService whose job it is to
load ZConfig schemas and cache them. That could be done in a property
namespace, e.g.:
[peak.ZConfig.schemas]
myApp.schemaX = "file:/path/to/the/schema.xml"
myApp.schemaY = "pkgfile:my.app/schemaY.xml"
and then we could have 'zconfig' URLs like
'zconfig:schemaX:urlOfFileToParse', so then we'd have just:
[ourapp.plugins]
foo = naming.LinkRef("zconfig:myApp.schemaX:fileY")
bar = naming.LinkRef("zconfig:myApp.schemaX:fileZ")
...
In order to have loaded-on-demand ZConfig components with easy-to reference
schemas. Indeed, you could use these URLs in component bindings as well,
although the value there is somewhat less.
More information about the PEAK
mailing list