Hi there, I took a few minutes to write down a draft of a requirement document for the configuration override mechanism.
James : I integrated your part of the configuration group merge in the doc, tell me if that's ok for you. Here is the draft (attached as well): Zeta Components : configuration override system, spec ===================================================== :Author: Jérôme Renard, James Pic :Revision: $Revision$ :Date: $Date$ Introduction ============ Description ----------- The configuration package provides the tools to store configuration settings for your application. Configuration options are stored on disk using INI files or other configuration formats. The configuration package comes with support for manipulation and storage of INI files and caching. Current implementation ---------------------- The configuration package does not provide any mechanism to get a final setting value from several configuration directories. Requirements ============ The configuration override mechanism should be able to analyse a set of files and apply the correct override mechanism to generate the resulting configuration. Context aware configuration files --------------------------------- Creating a website requires to go through 3 different execution contexts: 1. dev 2. staging 3. production Each context has its own specificities. For example the database used for each of these 3 contexts is different. So this must be defined for each context and used according to the one the web application is actually running in. Those 3 contexts should be handled by the Configuration component, during the configuration directive merge process. Directory structure ------------------- In order to provide a clean directory structure the Configuration component should be able to read and understand a directory structure compared to this one: :: /[..]/conf/ |-- common | |-- dev | |-- prod | `-- staging `-- apps |-- app1 | |-- dev | |-- prod | `-- staging `-- app2 |-- dev |-- prod `-- staging Storing common configuration ---------------------------- All web applications have common configuration directives. So all common configuration files and directives should be stored in the `common/<context>/` directory. For example if all applications have to use the same database, it could be easy to create a `common/<context>/database.ini` file containing informations to connect to this database. Since each file is context specific it will be required to copy a file in all context directories. For example if you want to store database connection values for all project, you can create a file in `conf/<context>/database.ini` with the following contents: :: [DatabaseSettings] Host=localhost Password=1234 Port=1234 And this configuration will be available for all projects that use the `database.ini` file. Storing application specific configuration ------------------------------------------ Providing different applications with the same code base but configured differently is actually quite common as well. If for example you have a first application called projectA and another one called projectB it should be possible to have projectB inherit from projectA's configuration, as well as overriding some of projectA's configuration. As an example, if we have projectA with the following configuration, in `conf/apps/projectA/<context>/routes.ini` : :: [myapp.register] controller=AAAAAAAA railsRoute=register action=register template=register.ezt And for projectB you want to inherit from these values and override only a few ones, in `conf/apps/projectB/<context>/routes.ini`: :: [app.register] controller=BBBBBBBB After applying the configuration overrdie system, you should get at runtime for projectB: :: [myapp.register] controller=BBBBBBBB railsRoute=register action=register template=register.ezt Performance considerations -------------------------- Hitting the filesystem and appying the override mechanism requires a lot of ressources and will possibly be a memory hog. In order to avoid that a compilation system should be provided. The system would work as follows: 1. define any configuration file/group/directive you want 2. run the compiler 3. use the compiled version with merged configuration directive for subsequent requests. Caching ------- If the directive configuration are compiled, it should be possible to control where the compiled version should be stored, for example in APC, or memcached so you can share these configuration directive across multiple servers. That would required a TieIn between the Configuration and the Cache component. Reading a configuration directive --------------------------------- This require a modification of the actual API to handle the execution context. Writing a configuration directive --------------------------------- This require a modification of the actual API to handle the execution context. FAQ --- Why do not you provide context override as well ? +++++++++++++++++++++++++++++++++++++++++++++++++ The override system already provide an horizontal override system, i.e each file override another if it is in the same context. Providing a context override mean that it will require a vertical override system as well and is extremley complex to implement. Even though it is an interesting idea, it is safer to keep it for future versions of the Configuration component. Any comment welcome :) -- Jérôme Renard http://39web.fr | http://jrenard.info
zetacomponent-configurationoverride.rst.gz
Description: GNU Zip compressed data
