The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Helios::Config - base class for Helios configuration system

SYNOPSIS

 # to determine a service's config based on
 # a particular conf file and host
 use Helios::Config;
 Helios::Config->init(
     CONF_FILE => '/path/to/helios.ini',
     HOSTNAME  => 'host',
     SERVICE   => 'ServiceName'
 );
 my $config = Helios::Config->parseConfig();
 
 # if $HELIOS_INI env var is set and current host is used
 use Helios::Config;
 Helios::Config->init(SERVICE => 'ServiceName');
 my $config = Helios::Config->parseConfig();
 
 # same as above; parseConfig() will automatically call init()
 use Helios::Config;
 my $config = Helios::Config->parseConfig(SERVICE => 'ServiceName');
 
 # you can also use accessor methods; for example, with Helios::TestService:
 use Helios::Config;
 Helios::Config->setServiceName('Helios::TestService');
 Helios::Config->init();
 my $config = Helios::Config->parseConfig();

 # catch config errors with eval {}
 # Try::Tiny works too 
 use Helios::Config;
 my $config;
 eval {
        Helios::Config->init(SERVICE => 'Helios::TestService');
        $config = Helios::Config->parseConfig();
 } or do {
        my $E = $@;
        if ( $E->isa('Helios::Error::ConfigError') ) {
                print "Helios configuration error: $E\n";
        } else {
                print "I do not know what happened, but it was bad.\n";
        }
 };
 

DESCRIPTION

Helios::Config is the standard class for determining configuration information in the Helios framework. It handles parsing configuration information from the Helios configuration file, and determining the configuration for services from information in the Helios collective database. Helios::Config also acts as a base class for the Helios configuration API; services can define specialized Helios::Config subclasses to extend configuration subsystem functionality.

Normally, the developer of Helios services does not need to interact with Helios::Config directly. Helios normally handles all configuration transparently during service setup before a service's run() method is called. A Helios service need only call its getConfig() method to retrieve a hashref of its configuration parameters. Only those wanting to retrieve a Helios service configuration outside of the service (e.g. to write an external utility as an adjunct to a Helios service) or those with advanced configuration needs will need to work with Helios::Config directly.

It should be noted that, like Helios::Logger subclasses, Helios::Config methods are actually class methods, not instance (object) methods. If you need to implement other methods outside of the methods defined below, make sure you implement them as class methods.

ACCESSOR METHODS

Helios::Config provides 7 set/get accessor pairs to provide access to configuration data. There are 3 categories of accessors: ones that need to be set before configuration parsing is initialized, those that are used during configuration parsing, and those that hold the end results of the parsing procedure (i.e. the actual configuration helios.pl and the Helios service will need).

INITIALIZATION ACCESSORS

These need to be set before configuration parsing is initialized with the init() method. If they are not set, the init() method will try to set them from data in the environment.

 set/getConfFile()        path to the Helios conf file 
                          -defaults to $HELIOS_INI env variable
 set/getHostname()        hostname the Helios service is running on
                          -defaults to results of Sys::Hostname::hostname()
 set/getServiceName()     name of the running Helios service
                          -defaults to undefined, which will cause the
                           resulting config to contain the contents of the 
                           helios.ini [global] section only

CONFIG PARSING ACCESSORS

These methods will be set during the configuration parsing process. Most Helios service developers will not need to be aware of these, but if you are developing a specialized Helios::Config subclass, they may be useful.

 set/getConfFileConfig()  the config info parsed from helios.ini
 set/getDbConfig()        the config info parsed from the collective database
 set/getDriver()          Data::ObjectDriver object connected to collective db

PARSING RESULTS ACCESSORS

This method contains the results of the configuration parsing process. In other words, the actual configuration information for the given Helios service.

 set/getConfig()          the complete config info from both conf file & db

CONFIGURATION INITIALIZATION METHODS

init([%params])

Prepares Helios::Config to parse the configuration for a particular Helios service. Accepts initialization information as a hash of parameters; if a parameter is not given, init() will attempt to default to values based on information from the environment.

The init() method accepts 4 arguments:

 CONF_FILE  path to the helios.ini file (default: $HELIOS_INI env var)
 HOSTNAME   hostname (default: current hostname from Sys::Hostname::hostname())
 DEBUG      enable/disable debug mode (default: disabled)
 SERVICE    name of the Helios service to determine configuration for 
            (default: none)

For example, to initialize Helios::Config to parse the configuration information from /etc/helios/helios.ini for the Helios::TestService service on the host named host1.hosting.com, one would call init() as:

 Helios::Config->init(
        CONF_FILE => '/etc/helios/helios.ini',
        HOSTNAME  => 'host1.hosting.com',
        SERVICE   => 'Helios::TestService'
 );

Normally the host and config file are specified by the operating system and the $HELIOS_INI environment variable, so a more typical init() call in a properly set up Helios collective would only specify the service:

 Helios::Config->init(SERVICE => 'Helios::TestService');

CONFIGURATION PARSING METHODS

parseConfig([%params])

Given a set of optional initialization parameters, parseConfig() will parse the helios.ini config file and query the Helios collective database for configuration information for a particular Helios service, combining the information into a single set of configuration information, which is returned to the calling routine as a hash reference.

The parseConfig() method controls the actual parsing and derivation of a service's configuration. This process has 4 steps:

  • Initialization (optional)

    If parseConfig() was given options, it will call the init() method to (re-)initialize the configuration parsing process. If no options were specified, parseConfig() assumes all the necessary options have already been set.

  • Conf file parsing

    If the configuration file has not yet been parsed, parseConfig() calls parseConfFile() to parse it. If the conf file information has already been parsed, parseConfig() skips this step. This is to ensure the helios.pl daemon and Helios worker processes do not become unstable if the filesystem with the config file becomes unmounted.

    See the parseConfFile() method entry for more information about this phase of configuration parsing.

  • Conf database parsing

    Given the information obtained in the previous step, parseConfig() calls the parseConfDb() method to query the Helios collective database for configuration information for the specified Helios service. Unlike the previous step, parseConfig() always calls parseConfDb(). This is so the helios.pl daemon and Helios worker processes can dynamically update their configuration from the database.

    See the parseConfDb() method entry for more information about this phase of configuration parsing.

  • Merging configurations

    Once the configurations from the conf file and the database have been acquired, parseConfig() merges the config hashes together into a single hash of configuration parameters for the specified service. This single config hashref is returned to the calling routine. A cached copy is also made available via the getConfig() method.

    Configuration parameters for a service specified in the collective database override parameters specified in the conf file.

    NOTE: Prior to Helios::Config, Helios assembled configuration parameter hashes differently. Originally, both helios.ini and database config parameters were reparsed each time a config refresh was requested, and the new parameters were merged with the old configuration values. This caused config values to "stick" even if they were completely deleted from the database or conf file. For example, deleting a HOLD parameter was not enough to take a service out of hold mode; the Helios administrator had to set HOLD to 0.

    Helios::Config merges configurations differently. Though the conf file config is only parsed once, each refresh of the database config starts with a new hash, and the config merge process starts with a brand new hash as well. That way the config hash returned by parseConfig() contains only the current config parameters, leading to a more predictable configuration subsystem.

parseConfFile([$conf_file, $service_name])

Given an optional conf file and an optional service name, parseConfFile() parses the conf file and returns the resulting hashref to the calling routine. It also makes the hashref available via the getConfFileConfig() accessor. If either the conf file or the service is not specified, the values from the getConfFile() and/or getServiceName accessor(s) are used. The conf file location is set by init() to the value of the $HELIOS_INI environment variable unless otherwise specified.

The default Helios configuration file is the common .ini file format, where section headings are denoted by brackets ([]). Lines not starting with [ are considered parameters belonging to the last declared section. Lines starting with # or ; are considered comments and are ignored. See Config::IniFiles (the default underlying file parser) for more format details.

Helios requires at least one section, [global], in the conf file, which should contain at least 3 parameters:

 dsn       DBI datasource name of the Helios collective database
 user      the user to use to access the Helios collective db
 password  the password to use to access the Helios collective db

Without these, the helios.pl daemon will be unable to connect to the collective database and will fail to start.

You may also specify other configuration parameters in the [global] section. Options set in the [global] section will appear in the configuration parameters of all services using that conf file. This can be useful if you need multiple services on a host to share a configuration (e.g. you want to configure all services on a host to log messages to a syslogd facility using HeliosX::Logger::Syslog).

In addition to [global], you can create other sections as well. If a section name matches the service name specified, the configuration parameters in that section will be included in the config hash returned to the calling routine. You can use this feature to set defaults for a service, or to set sensitive parameters (e.g. passwords) that you do not want to be changable from the Helios::Panoptes web admin console.

For example, a Helios conf file that configures the Helios collective db and sets some config parameters for the Helios::TestService service would look something like:

 [global]
 dsn=dbi:mysql:host=dbhost;db=helios_db
 user=helios_user
 password=xyz123
 
 [Helios::TestService]
 MAX_WORKERS=1
 loggers=HeliosX::Logger::Syslog
 syslog_facility=user
 syslog_options=pid

parseConfDb([$service_name, $hostname])

The parseConfDb() method queries the Helios collective database for configuration parameters matching the specified service name and hostname and returns a hashref with those parameters to the calling routine. If the service name and hostname are not specified, the values returned from the getServiceName() and getHostname() accessors are used. The getHostname() value is normally set by init() to the value returned by Sys::Hostname::hostname() unless otherwise specified.

The default parseConfDb() queries the HELIOS_PARAMS_TB table in the Helios collective database. Two separate queries are done:

  • Config params matching the service name and a host of '*'. Config params with a '*' host apply to all instances of the service in the entire collective.

  • Config params matching the service name and the current hostname. Config params with a specific hostname apply only to instances of that service on that particular host. These are useful for HOLDing or HALTing services only on one host, or working with differences between hosts (e.g. a host with 4 cores and 16GB of RAM can support a higher MAX_WORKERS value than a dual core system with 2GB of memory).

The results of these two queries are merged, and the resulting hashref returned to the calling routine. Config parameters for a specific host override config params for all ('*') hosts.

Configuration parameters in the Helios collective database can be set using the Helios::Panoptes web admin console or using your database's standard SQL commands.

getParam(param => $param_name [, service => $service_name] [, hostname => $hostname])

Given a service name, parameter name, and (optionally) a hostname, getParam() returns the parameter name's value to the calling routine.

If hostname is not specified, the current host is assumed.

setParam(param => $param_name [, service => $service_name] [, hostname => $hostname], value => $value)

Given a service name, parameter name, parameter value, and (optionally) a hostname, setParam() sets the value for that parameter for that service (and host) in the Helios collective database. If hostname is not specified, the current host is assumed. To set a parameter for all instances of a service in a collective, set the hostname to '*'.

unsetParam(param => $param_name [, service => $service_name] [, hostname => $hostname,])

Given a service name, parameter name, and (optionally) a hostname, unsetParam() deletes that parameter's entry in the Helios collective database.

If hostname is not specified, the current host is assumed. To unset a parameter that is in effect for all instances of a service, you must set the hostname to '*'.

EXTENDING HELIOS::CONFIG

Helios service developers with more advanced configuration needs than Helios::Config supplies can extend the Helios::Config class to override its methods and/or provide methods of their own. There are 2 steps required to take advantage of this functionality:

  • Extend Helios::Config

    In defining a Helios::Config subclass, there are 2 important methods that drive the configuration parsing process: init() and parseConfig(). Without these methods, the Helios framework will be unable to use the new config class.

  • Set the ConfigClass() method in your Helios service

    Just like JobClass() with jobs, ConfigClass() defines an alternate class to use to perform configuration parsing for your particular Helios service. For example:

     package MyService;
     
     use 5.010;
     use strict;
     use warnings;
     use parent 'Helios::Service';
     
     use MyConfig;
     
     sub ConfigClass { 'MyConfig' }
    
     sub run {
            my $self = shift;
            my $job = shift;
            my $config = $self->getConfig();
            my $args = $self->getJobArgs($job);
            
            ....
     }
     
     1;

HELIOS CONFIGURATION PARAMETERS

The Helios system itself defines a large number of configuration parameters to control the helios.pl daemon, worker launching, and other system tasks. Consult the Helios::Configuration page for a full list of parameters and their functions.

AUTHOR

Andrew Johnson, <lajandy at cpan dot org>

COPYRIGHT AND LICENSE

Copyright (C) 2012-4 by Logical Helion, LLC.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.0 or, at your option, any later version of Perl 5 you may have available.

WARRANTY

This software comes with no warranty of any kind.