[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