Skip to content

Commit

Permalink
Merge config --> develop
Browse files Browse the repository at this point in the history
Conflicts:
	lib/webserver/index.js
  • Loading branch information
itayw committed Dec 3, 2013
2 parents 8721290 + cdfbd36 commit d0d2916
Show file tree
Hide file tree
Showing 17 changed files with 424 additions and 154 deletions.
94 changes: 94 additions & 0 deletions config/baseline.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"id": "joola.io-config-baseline",
"description": "This is a baseline configuration file for joola.io",
"moreinfo": "https://github.com/joola/joola.io/wiki",

"_version": "0.0.1",

"interfaces": {
"webserver": {
"enabled": true,
"port": 40008,
"securePort": 40009,
"secure": false,
"keyFile": null,
"certFIle": null,
"websocket": {
"enabled": true
},
"sessionDurtaion": 1200000
},
"repl": {
"enabled": true,
"port": "1337"
},
"beacon": {
"enabled": true,
"port": "50008"
}
},
"store": {
"config": {
"redis": {
"host": "localhost",
"port": 6379,
"db": 10
}
},
"dispatch": {
"redis": {
"host": "localhost",
"port": 6379,
"db": 1
}
},
"stats": {
"redis": {
"host": "localhost",
"port": 6379,
"db": 2
}
},
"logger": {
"mongo": {
"uri": "mongodb://localhost/logger"
},
"fs": {
"path": "/var/log/joola.io"
}
},
"beacon": {
"mongo": {
"uri": "mongodb://localhost/beacon"
}
},
"cache": {
"mongo": {
"uri": "mongodb://localhost/cache"
}
}
},
"engine": {
"cache": {
"lockTimeout": 5000,
"waitOnCache": 5000,
"waitInterval": 500
},
"query": {
"results": {
"cache": {
"enabled": false,
"expire": 0
}
}
}
},
"logging": {
"level": "silly",
"stores": ["mongo", "fs"]
},
"dispatch": {
"ttl": 5000,
"expires": 6
}
}
18 changes: 18 additions & 0 deletions docs/about-joolaio/_Sidebar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
**ABOUT JOOLA.IO**

**Introduction**
- [joola.io overview](joolaio-overview)
- [[Technical architecture|technical-architecture]]

**Thanks**
- Sponsors
- [Software and services](Software-and-services-thanks)
- [Contributors](Our-contributors)

**Useful resources**
- [[FAQ]]
- [[Troubleshooting]]
- [[Contributing]]

**External resources**
- [joola.io website](http://joola.io)
6 changes: 6 additions & 0 deletions docs/about-joolaio/technical-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
joola.io's **Events Sub-system** has a non-traditional design to support both local and distributed communication.

The sub-system is divided into two parts:
* ``joola.dispatch`` provide distributed redis-based pub/sub events shared between all nodes.
* ``joola.events`` provide a local events system based on emit/on that most of us are familiar with.

6 changes: 3 additions & 3 deletions lib/common/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ cli.usage = function () {
*/
cli.process = function () {
var shouldExit = false;
if (joola.config.get('version')) {
if (process.argv.indexOf('--version') > -1) {
console.log('v' + joola.VERSION);
shouldExit = true;
}
if (joola.config.get('help')) {
if (process.argv.indexOf('--help') > -1) {
cli.usage();
shouldExit = true;
}
if (joola.config.get('nolog')) {
if (process.argv.indexOf('--nolog') > -1) {
global.nolog = true;
}

Expand Down
127 changes: 108 additions & 19 deletions lib/common/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,127 @@
* Some rights reserved. See LICENSE, AUTHORS.
**/


var
path = require('path'),
nconf = require('nconf');

require('nconf-redis');

module.exports = nconf;


nconf.argv()
.env();

require('nconf-redis');
nconf.init = function (callback) {
var rawConfig = null;
var options = {
redis: {}
};

nconf.options = options;

var config = module.exports = function (options) {
var options_redis = {
host: 'localhost',
port: 6379,
DB: 0
options.redis = {
namespace: 'config',
connect: function () {
joola.logger.debug('[config-redis] Connected to redis @ ' + nconf.options.redis.host + ':' + nconf.options.redis.port + '#' + nconf.options.redis.db);
joola.state.set('config-redis', 'working', 'redis [config-redis] is up.');
},
error: function (err) {
joola.state.set('config-redis', 'failure', 'redis [config-redis] is down: ' + err);
}
};

joola.config = nconf;
joola.config.use('redis', { host: options_redis.host, port: options_redis.port, ttl: 0, db: options_redis.DB });
var configPath = path.join(__dirname, '../../config/baseline.json');
//we don't have a valid redis store yet, let's find a config file.
nconf.file({ file: configPath });

var redis = joola.config.stores.redis.redis;
redis.on('connect', function () {
joola.state.set('config-redis', 'working', 'redis [config-redis] is up.');
});
redis.on('error', function (err) {
joola.state.set('config-redis', 'failure', 'redis [config-redis] is down: ' + err);
rawConfig = require(configPath);

options.redis.host = nconf.get('store:config:redis:host');
options.redis.port = nconf.get('store:config:redis:port');
options.redis.db = nconf.get('store:config:redis:db') || 0;
options.redis.auth = nconf.get('store:config:redis:auth');

if (options.redis.host === null || options.redis.port === null || options.redis.db === null) {
//we still don't have any valid redis config.
return callback(new Error('Failed to find a valid config file [' + configPath + '].'));
}
else
joola.logger.silly('Loaded configuration from [' + configPath + ']');

joola.config.use('redis', options.redis);
joola.config.redis = joola.config.stores.redis.redis;

//check that we have a valid configuration
joola.config.get('version', function (err, value) {
if (err)
return callback(err);

if (!value) {
joola.logger.warn('Found an empty configuration store, building initial...');
Object.keys(rawConfig).forEach(function (key) {
joola.config.set(key, rawConfig[key]);
});
joola.config.set('version', rawConfig._version);
}
else {
joola.logger.silly('Found a valid configuration store.');
}

joola.config.redis.smembers(nconf.stores.redis.namespace + ':keys', function (err, keys) {
if (err)
return callback(err);

var counter = 0, expected = keys.length;
if (expected === 0)
return callback(null);

keys.forEach(function (key) {
joola.config.get(key, function (err, value) {
counter++;
joola.config[key] = value;
if (counter == expected) {
joola.events.emit('config:done');
return callback(null);
}
});
});
});
});

//this is needed to override output of errors by nconf-redis in case of disconnect
console.dir = function (data) {
//override set
joola.config._set = joola.config.set;
joola.config.set = function (key, value, expire, callback) {
if (typeof expire === 'function') {
expire = null;
callback = expire;
}
callback = callback || function () {
};

joola.config._set(key, value, function (err) {
if (err)
return callback(err);

joola.dispatch.emit('config', 'change', {}, function () {

});
if (expire)
joola.config.redis.expire(joola.config.namespace + ':' + key, expire);
return callback(null);
});
};

return joola.config;
};
//hook events
joola.events.on('dispatch:ready', function () {
joola.dispatch.on('config', 'change', function (err, message) {
if (err)
joola.logger.error('Error while changing configuration deteched: ' + err);

joola.config.init(function (err) {
joola.logger.info('Cache store refreshed due to a change.');
});
});
});
};
50 changes: 27 additions & 23 deletions lib/common/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,33 @@
var
domain = require('domain');

if (process.env.NODE_ENV != 'test')
{
joola.domain = process.domain = domain.create();
joola.domain.on('error', function (domain, err) {
console.log('ERROR! ' + domain, err);
console.log(err.stack);
if (process.env.NODE_ENV != 'test') {
joola.domain = process.domain = domain.create();
joola.domain.on('error', function (domain, err) {
console.log('ERROR! ' + domain, err);
if (err.stack)
console.log(err.stack);
else
console.trace();

joola.logger.error('FATAL EXCEPTION! ' + err.message);
joola.logger.debug(err.stack);
shutdown(1);
});
process.on('uncaughtException', function (exception) {
console.log('FATAL EXCEPTION: ' + exception.message);
console.log(exception.stack);
joola.logger.error('FATAL EXCEPTION! ' + err.message);
if (err.stack)
joola.logger.debug(err.stack);
shutdown(1);
});
process.on('uncaughtException', function (exception) {
console.log('FATAL EXCEPTION: ' + exception.message);
if (exception.stack)
console.log(exception.stack);

joola.logger.error('FATAL EXCEPTION: ' + exception.message + '\n' + exception.stack, null, function () {
global.shutdown(1);
joola.logger.error('FATAL EXCEPTION: ' + exception.message + '\n', null, function () {
global.shutdown(1);
});
});
process.on('exit', function () {
global.shutdown(0);
});
process.on('SIGINT', function () {
global.shutdown(0);
});
});
process.on('exit', function () {
global.shutdown(0);
});
process.on('SIGINT', function () {
global.shutdown(0);
});
}
}
2 changes: 1 addition & 1 deletion lib/common/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ var
var _events = new EventEmitter2({wildcard: true, newListener: true});
_events._id = 'events';

module.exports = exports = _events;
module.exports = exports = _events;
2 changes: 1 addition & 1 deletion lib/common/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ global.shutdown = function (code) {
if (stopped)
return;
joola.logger.info('Gracefully shutting down, code: ' + code);
joola.state.set('core', 'stop', 'received code' + code);
joola.state.set('core', 'stop', 'received code [' + code + ']+');
joola.dispatch.emitWait('nodes', 'state:change', [joola.UID, joola.state.get()], function () {
stopped = true;
process.exit(code || 0);
Expand Down

0 comments on commit d0d2916

Please sign in to comment.