yahoo/cerebro

Name: cerebro

Owner: Yahoo Inc.

Description: null

Created: 2017-07-13 15:42:29.0

Updated: 2018-02-23 21:55:49.0

Pushed: 2017-11-16 16:39:21.0

Homepage: null

Size: 53

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Cerebro

Build Status Coverage Status

A generic configuration system for Node.js.

Cerebro receives two inputs:

Cerebro outputs the resolved configuration.

Usage
rt Cerebro from 'cerebro';

t configuration = [{
tting: 'timer',
lue: 30,
cept: [{
value: 15,
environment: ['alpha']



t context = {
vironment: 'alpha'


nitialize Cerebro
t cerebro = new Cerebro(configuration);
t resolvedConfiguration = cerebro.resolveConfig(context);

ole.log(resolvedConfiguration);
> { timer: 15 } because the setting `timer` is set to 15 when the environment is alpha.
or all other environments, the resolvedConfiguration would be { timer: 30 }
Configuration Rules

For configuration, Cerebro expects an array that contains objects that have a setting and a value. setting is the name of the configuration setting, and value is the value that will be assigned to it. value can be any JSON data type.

Here is an example configuration object:


tting: 'timer',
lue: 30,
cept: [{
value: 15,
environment: ['alpha']


Settings must explicitly set the value in the except blocks.

Settings are expected to follow these rules:

Settings are defined formally in src/validators/schema.json.

Evaluation Order

If all the criteria in an except block is met, the value in the except block will be used. The except blocks are checked in order, and it exits once it finds a match. If no except block matches fully, then the default value is used.

Here is an example:

rt Cerebro from ('cerebro');

t configuration = [{
tting: 'timer',
lue: 30,
cept: [{
value: 15,
environment: ['alpha']
 {
value: 20,
environment: ['alpha'],
bucket: 'a'



t context = {
vironment: 'alpha',
cket: 'a'


nitialize Cerebro
t cerebro = new Cerebro(configuration);
t resolvedConfiguration = cerebro.resolveConfig(context);

ole.log(resolvedConfiguration);
> { timer: 15 } because the setting `timer` is set to 15 when the environment is alpha.
n this case, {timer: 20} would never be hit because {timer: 15} will cause the evaluation
o end immediately when environment is alpha
Supported Formats for Context Checks in Except
Enums

Given an except block that accepts multiple values for the same dimension, enable the setting if a dimension in the context object matches one of those values. For example, if the configuration has something like this:


tting: 'enableNewFeature',
lue: false,
cept: [{
value: true,
bucket: ['a', 'b']


The setting should be enabled if the context object contains the dimension bucket: 'a' or bucket: 'b'.

Enums also support two additional options, none and all. Here's what the configuration would look like:


setting: 'enableNewFeature',
value: false,
except: [{
    value: true,
    partner: [
        'all'
    ]
}]

In this case, if the context object contains any partner, the setting will be enabled. If the context contains no partner, the setting will be disabled. In other words, the setting is only enabled for partners.


tting: 'enableNewFeature',
lue: false,
cept: [{
value: true,
partner: ['none']


Similar logic applies to none. If the context contains no partner, the setting will be enabled. If the context contains any partner, the setting will be disabled. In other words, the setting is disabled only for partners.

Ranges

A configuration may contain a range of values. The range may be inclusive or exclusive.

An inclusive range looks like this: rangeExample: ['1000..2000']. An exclusive range looks like this: rangeExample: ['1000...2000'].

Here?s an example of a setting using a range:


tting: 'enableNewFeature',
lue: false,
cept: [{
value: true,
userBirthdayYear: ['2000...2010']


Thus, if the context contains a dimension called userBirthdayYear that is anywhere between 2000 and 2010, exclusive, the setting will be enabled.

Setting Dependency

One setting may depend on another setting. In this case, the configuration would look something like this:


tting: 'independent',
lue: false,
cept: [{
value: true,
environment: ['alpha']


tting: 'dependent',
lue: false,
cept: [{
value: true,
setting: 'independent'


In this case, the dependent setting will not be enabled unless the independent setting is also enabled.

Custom Evaluators

We may want to evaluate a context in a custom way. For example, we may want to use do a partial string match using a regex.

Below is an example of the configuration:


setting: 'enableNewFeature',
value: false,
except: [{
    value: true,
    partialLocale: ['en']
}]

To use a custom evaluator, you must pass an object called customEvaluators through the options object in the Cerebro constructor. This object will have the name of the dimension it is to evaluate as a key and the evaluation function as value.

The evaluation function will receive two parameters, a dimensionValue, which is the value given in the configuration (en in the above example), and testValue, which is the value passed in the context.

The evaluation function must return a boolean. If it does not return a boolean, the return value will be coerced to a boolean.

For the above configuration, the customEvaluators would look like this:

var customEvaluators = {

customDimension: function(dimensionValue, testValue) {}

};

The dimensionValue would be [?en?], and the testValue would be whatever the value of customDimension was in the context.

Overrides

We may want to override a certain setting, regardless of what the configuration says. To do this, the client must pass an object, overrides, into the Cerebro constructor. The keys of the overrides object will be the setting names and the value will be the value of the setting. Typically, these overrides would come from the request URL, but any source can be used.

Thanks

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.