Skip to content
This repository has been archived by the owner on Aug 13, 2020. It is now read-only.

Configuration

Harald Gustafsson edited this page Oct 12, 2017 · 10 revisions

Once Calvin is installed, preferably in a virtualenv, there are some additional tricks that can may be useful. Please note that changing the configuration should not be necessary for normal operation.

Say that I'm working on an application in some project directory and as part of that project I need to develop a couple of new actors. Since they are not quite ready for the world yet, I'd like to keep them in a separate directory with my application.

Let's have a look at Calvin's config system to find out how to solve that problem

Some basics

Calvin uses JSON as config format, and the default built-in config looks like this (actual contents is subject to change, but not the structure):

{
    "global": {
        "comment": "User definable section",
        "actor_paths": [
            "systemactors",
            "devactors"
        ],
        "framework": "twistedimpl",
        "remote_coder_negotiator": "static",
        "static_coder": "json"
    },
    "testing": {
        "comment": "Test settings",
        "unittest_loops": 2
    },
    "developer": {
        "comment": "Experimental settings"
    }
}

It is divided into sections (global, testing, and developer), and we allow the use of a special key comment to add any kind of text as the value (comment keys will be skipped by the config reader). The global section is the one to use for general changes, whereas the testing section is read by the testing frameworks and the developer section is a place to store information that would typically only be used by you during development. N.B. The name global has nothing to do with the scope of the settings, it is just a name.

A config file should be named calvin.conf or .calvin.conf and Calvin will look for config files in the following places (in the listed order):

  1. Calvin's install directory
  2. Users home directory
  3. All directories between the current working directory and users home directory
  4. The current working directory

If the current working directory is outside of users home directory, e.g /opt/local/calvin/test/, only (1), (2) and (4) are searched. The last seen config file will have the highest priority, and what happens depends on the kind of value read. Simple values (numbers, booleans, strings, and null) are overwritten by later configs, whereas lists are prepended by later configs.

Configuring actor search paths

By default Calvin will look for actors in systemactors/ and devactors/ inside its install directory. We can add more actor search paths to Calvin by creating one or more config files.

Thus, if I wan't add my local actors I can simply drop a calvin.conf file with the following content in my development directory (e.g. /home/fuzzbar/source/testing) :

{
  "global": {
    "actor_paths": ["./actors"]
  }
}

The effect is that Calvin will now look for actors in /home/fuzzbar/source/testing/actors, systemactors, devactors, in that order.

Actor search paths can be specified in three ways:

  1. relative to the install, e.g. systemactors or devactors, and is generally not useful outside the default config,
  2. relative to the location of the config file, e.g. ./actors, which is useful in the example case above, and
  3. as absolute paths, e.g. /opt/local/shared_actors, which is useful for a config file residing in a home directory and applies to all Calvin projects.

Configuring transports plugins

By default Calvin registers calvinip as an possible transport interface, additional interfaces to register can be specified with "transports" in calvin.conf:

{
  "global": {
    "transports": ["calvinbt"]
  }
}

Configuring a Control API proxy

A remote Calvin runtime can be used as an proxy for the Control API by specifying the uri in calvin.conf:

{
  "global": {
    "control_proxy": "calvinbt://E8:B1:FC:F1:87:AD:1"
  }
}

Configuring a storage proxy

A remote Calvin runtime can be used as a registry proxy by specifying the uri in calvin.conf:

{
  "global": {
    "storage_proxy": "calvinbt://E8:B1:FC:F1:87:AD:1"
  }
}

See below for more information on the registry.

Overriding configs temporarily

Sometimes, e.g. when debugging, it is useful to override the normal config setup and there are three independent ways of doing so:

  1. The environment variable CALVIN_CONFIG_PATH can be set to a colon-separated list of paths that will be searched after the default directories (1) through (4) above.

  2. In order to completely bypass the standard config paths, the environment variable CALVIN_CONFIG can be set to point to a config file that will be taken as the only configuration file, disregarding even the built-in settings.

  3. Using wildcard environment variables on the form CALVIN_<SECTION>_<OPTION> overrides options read from defaults or config files. <SECTION> must be one of GLOBAL, TESTING, DEVELOPER, or ARGUMENT, e.g. CALVIN_TESTING_UNITTEST_LOOPS=42

Getting configuration information

When running a script with loglevel set to DEBUG or higher Calvin will show a great deal of information: the configuration, the paths searched for config files, the paths where config files where found, and all wildcard environment variables.

Registry

All Calvin runtimes uses a registry for information about nodes, actors, ports, etc. The default type is a Distributed Hash Table (DHT), but this is a plug-in and other solutions are possible. The registry cannot be accessed directly, instead the Calvin control API is used from outside of the runtime. This API utilizes the registry to respond to requests about nodes, actors, index etc.

Internal to the runtime calvin.runtime.north.storage implements the interface.

All values aare key addressable, i.e. like a dictionary.

Distributed Hash Table

The DHT implementation is eventually consistent and stores the data on multiple nodes. So it should handle runtimes comming and going, but during tests it could be a bit extreme that a majority of the runtimes come and go constantly. During normal operation, it is rather expected that the majority of runtimes are long lived.

During tests we have seen some issues with the DHT due to which runtimes are responsible for a key changes so quickly that the key is not redistributed correctly.

Configuration

Three configuration parameters, storage_type, storage_proxy and storage_sql, exist in the global section of the configuration. The reason for using the prefix storage_ is historical, but the gist is that storage_ should be pronounced registry_.

Registry type

Normally a runtime have an internal, local, registry and one remote registry (defaults to a Distributed Hash Table, DHT). The internal local registry is flushed to the remote as soon as it is operational (has started). The storage_type defaults to dht, but it could be set to local, proxy or sql which starts respective other registry types.

The local and proxy types are useful when running on only a single runtime or - as we see in next section - when wanting to act as the sole registry server for proxy clients. The sql type can be used when having access to a central SQL database.

Registry proxy

Normally this configuration is null (i.e. undefined) which configures the registry to act as a potential registry proxy. It will then perform registry operations on behalf of proxy clients connecting to it. When storage_proxy is set to a runtime URI e.g. of the format calvinip://<addr>:<port> the runtime will connect to the specified runtime and use it as remote registry.

Registry SQL (currently only in develop branch)

The storage_sql contains a dictionary of keyword arguments used to connect to the SQL-database. The default is for a local mysql database having root user without password, good for testing but not much else (all runtimes need to access the same database). The keywords that can be set are:

  • dbmodule - The default is "MySQLdb" which is a standard MySQL python module, this is the only that have been tested.
  • db - The database name, must be identical on all that have a common registry.
  • host - The server host name, must be identical on all that have a common registry.
  • port - The database server port number, must be identical on all that have a common registry.
  • user - The database user name, must currently have right to create database db.
  • passwd - The user's password.

In the future the SQL authentication will use the normal Calvin security system.

Proxy Example Usage

When wanting to have a simple registry e.g. for small test, one runtime can be created with storage_type set to local to act as an internal only registry server:

CALVIN_GLOBAL_STORAGE_TYPE=\"local\" csruntime -n $IP_ADDR -p 5010 -c 5011 &

(Here IP_ADDR should be defined as the ip address of the computer.) We use the environment variable CALVIN_GLOBAL_STORAGE_TYPE to override the default configuration.

Then other runtimes can be created referring to the first runtime as their registry proxy.

CALVIN_GLOBAL_STORAGE_TYPE=\"proxy\" CALVIN_GLOBAL_STORAGE_PROXY=\"calvinip://$IP_ADDR:5010\" csruntime -n $IP_ADDR -p 5000 -c 5001 &
CALVIN_GLOBAL_STORAGE_TYPE=\"proxy\" CALVIN_GLOBAL_STORAGE_PROXY=\"calvinip://$IP_ADDR:5010\" csruntime -n $IP_ADDR -p 5002 -c 5003 &

Now the registry is handled by the first runtime in its internal registry.

N.B. the escaped quotes \" are required since the value we are passing must be a valid JSON type (string in this case).

For a small device which is not powerful enough to handle being part of the DHT, start the runtime with CALVIN_GLOBAL_STORAGE_TYPE and CALVIN_GLOBAL_STORAGE_PROXY set to point to another runtime (that is not also a proxy client.) Then the larger runtimes will by default setup the DHT between them and maintain the distributed storage.

SQL Example Usage (currently only in develop branch)

First a mysql server needs to be installed and started, you also might need to configure it for access and setting up users, see for example MySQL getting started.

Next you need the correct python module:

pip install MySQL-python

Then you could start a runtime that connects to the local running MySQL server.

CALVIN_GLOBAL_STORAGE_TYPE=\"sql\" CALVIN_GLOBAL_STORAGE_SQL="{\"db\": \"calvin_registry\"}" csruntime -n $IP_ADDR -p 5010 -c 5011 &