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

Attachment: zetacomponent-configurationoverride.rst.gz
Description: GNU Zip compressed data

Reply via email to