• log out

General principles

The Qbix platform loads config from different JSON files in order, with each file dedicated to a particular purpose:

  1. Q_DIR/config/Q.json: basic defaults for the framework
  2. Q_DIR/Q/plugins/
    {$PLUGIN}/config/plugin.json
    : defaults for plugins used in the application. Loading order is defined in app config by key "Q/Q/plugins"
  3. APP_DIR/config/app.json: application specific config - version, used plugins, events etc.
  4. APP_DIR/local/app.json: any additional setting related to the server where application runs - web root, database connection info etc.

Let's imagine we have an app with a very heavy load which runs on a multiple machines, with a number of PHP workers and several node.js instances. In this case each machine will have its own set of config files listed above stored in its local storage system. If at some point, the administrator will decide to modify the config, each server in the cluster will need to eventually load the new config modified. During a given update period, some servers may have the old config and some servers will have the new one. After the period is complete, all servers are guaranteed to have the same config.

The platform uses an internal mechanism to address issues which may arise with the scaling of the application.

Consistency and Caching

Gathering multiple files from different locations consumes time and resources. Moreover, if config files are modified while application is gathering json files one by one, different worker processes may obtain different results. To avoid this, config files are loaded and stored as a complete snapshot.

In Node.js processes, the situation is simple. Config files are loaded at process start, and kept in memory until the process ends.

In PHP, config files are cached in APC storage and after first worker accesses the complete set of config files, it is consistently stored in the cache. Each next run of the scripts uses the snapshot from APC cache. For config consistency any change (save) of config file used by script is pushed to APC cache on script shutdown as single transaction, so next script which requests config from APC will see either all changes done by previous script or no changes at all.

If APC is not enabled, the traditional "load from files" routine is used. Also, changing config files in the file system "by hand" does not necessary preserve consistency and should be done offline.

Propagation

Having distributed application with multiple servers it's necessary to make sure that all workers on all servers reload config files from server storage when any file is modified. This is done is simple way - the complete config tree is reloaded once in a while. Reload period is defined by "Q/internal/configServer/interval" config value and defaults to 60 seconds.

Config modifications of applications which are online should only be done only with APC installed, and by calling dedicated Q_Config methods described below. After waiting at least the number of seconds in "Q/internal/configServer/interval" plus PHP timeout (defined by "Q/internal/phpTimeout"), you can be sure that all workers on all servers are now using the updated config.

Static and variable config.

Generally speaking, platform and plugin config files as well as APP_DIR/config/app.json and APP_DIR/local/app.json files are considered static and are not supposed to change over application lifetime, except when updated by their developer in a new version of the application. In a proper application install, these files should probably be write-protected. They form the static config.

Any changes made during the app's runtime (e.g. switching to other database or add shards, temporary block write access to database etc.) should be made within extra config files listed under "Q/configFiles" config key. Files listed under this key are searched in "APP_DIR/files" folder and thus are writable by application. We always attempt to load "Q/config/bootstrap.json", but if it does not exist, no error is reported. This is where we store the variable config.

In general, to modify some config value one should either set up this value in "Q/config/bootstrap.json" config file, or add a new config file under "APP_DIR/files" and then add its name to "Q/configFiles" config key in the "Q/config/bootstrap.json" file. In both cases the new config value will be eventually propagated to all workers after the update period.

Config Server

If the application runs on different servers, the variable config files will be modified on each server. To avoid this, one server can be dedicated as config server and provide all variable config values to others. This can be done by defining "Q/internal/configServer/url" and "Q/internal/configServer/internal" values in APP_DIR/local/app.json on all machines.

  • "Q/internal/configServer/url" is the base url of the config server. It may be a simple url or array consisting of the url and ip address. In the second case the http request issued to config server will have its "Host:" header field set to the actual host from the url but will be addressed directly to the provided ip.
  • "Q/internal/configServer/internal" is a boolean value reflecting whether the config server is a Node.js internal server (true), or a PHP or Node.js server accessibe by ("http://yourapp.com/action.php") (false).

It's important to make sure that "Q/internal/configServer/url" is undefined or set to null on config server itself. Setting the value to "Q/internal/configServer/url" may cause an infinite loop of requests to server(s).

After config server is properly defined all requests for the files listed under "Q/configFiles" key will be directed to that server. Now it's easy to modify config value - just set it up on config server and wait for timeout. All application servers will get the updated config.

Config Handling Methods

To preserve config consistency, any variable config values must be set by using the corresponding Q_Config methods. If the config server is set up as in the previous section, these methods will issue requests to the config server to make modifications, otherwise the files will be modified locally.

There are three methods to change variable config:

  • Q_Config::getFromServer - get contents of config file,
  • Q_Config::setOnServer - modify a config file by merging over new data,
  • Q_Config::clearOnServer - modify a config file by clearing some data.

For moredetails, check the PHP or JS reference.