Cache client settings, emit event on reconfig in configuration.js
authorJack Allnutt <jack@allnutt.eu>
Sat, 10 Aug 2013 10:20:22 +0000 (11:20 +0100)
committerJack Allnutt <jack@allnutt.eu>
Sat, 10 Aug 2013 10:20:22 +0000 (11:20 +0100)
server/configuration.js
server/httphandler.js

index be89037208f9904afab89b042382a5549710831e..bc05e6ebd669adb00dda21f3dafa184d86fac109 100644 (file)
@@ -1,12 +1,18 @@
-var fs = require('fs');
+var fs      = require('fs'),
+    events  = require('events'),
+    util    = require('util');
 
 var config_filename = 'config.js',
     config_dirs = ['/etc/kiwiirc/', __dirname + '/../'],
     environment = 'production',
     loaded_config = Object.create(null);
 
+var Config = function () {
+    events.EventEmitter.call(this);
+};
+util.inherits(Config, events.EventEmitter);
 
-function loadConfig() {
+Config.prototype.loadConfig = function () {
     var new_config,
         conf_filepath,
         i;
@@ -39,23 +45,24 @@ function loadConfig() {
     if (new_config) {
         loaded_config = new_config;
         global.config = new_config[environment] || {};
+        this.emit('loaded');
         return loaded_config;
     } else {
         return false;
     }
-}
+};
 
 
 
-module.exports.setEnvironment = function (new_environment) {
+Config.prototype.setEnvironment = function (new_environment) {
     environment = new_environment;
 };
 
 // Get the current config. Optionally for a different environment than currently set
-module.exports.get = function (specific_environment) {
+Config.prototype.get = function (specific_environment) {
     specific_environment = specific_environment || environment;
     
     return loaded_config[specific_environment] || {};
 };
 
-module.exports.loadConfig = loadConfig;
+module.exports = new Config();
index 6a25aab11b2138bd9a8f42b7f26e40da7cb60ac1..d2a96954f8540090e0400f67912adfd76e996f28 100644 (file)
@@ -106,7 +106,17 @@ var serveFallbackLocale = function (request, response) {
     this.file_server.serveFile('/assets/locales/en-gb.json', 200, {Vary: 'Accept-Language', 'Content-Language': 'en-gb'}, request, response);
 };
 
-function serveSettings(request, response) {
+var cached_settings = {
+    hash: '',
+    settings: ''
+};
+
+config.on('loaded', function () {
+    cached_settings.settings = '';
+    cached_settings.hash = '';
+});
+
+function generateSettings(request, callback) {
     var vars = {
             server_settings: {},
             client_plugins: [],
@@ -216,8 +226,7 @@ function serveSettings(request, response) {
 
     fs.readFile(__dirname + '/../client/assets/src/translations/translations.json', function (err, translations) {
         if (err) {
-            response.statusCode = 500;
-            return response.end();
+            return callback(err);
         }
 
         var translation_files;
@@ -225,8 +234,7 @@ function serveSettings(request, response) {
         fs.readdir(__dirname + '/../client/assets/src/translations/', function (err, pofiles) {
             var hash;
             if (err) {
-                response.statusCode = 500;
-                return response.end();
+                return callback(err);
             }
 
             pofiles.forEach(function (file) {
@@ -236,18 +244,38 @@ function serveSettings(request, response) {
                 }
             });
 
-            hash = crypto.createHash('md5').update(JSON.stringify(vars)).digest('hex');
+            cached_settings.settings = JSON.stringify(vars);
+            cached_settings.hash = crypto.createHash('md5').update(cached_settings.settings).digest('hex');
 
-            if (request.headers['if-none-match'] && request.headers['if-none-match'] === hash) {
-                response.writeHead(304, 'Not Modified');
-                return response.end();
-            }
+            return callback(null, cached_settings);
+        });
+    });
+}
 
-            response.writeHead(200, {
-                'ETag': hash,
-                'Content-Type': 'application/json'
-            });
-            response.end(JSON.stringify(vars));
+function serveSettings(request, response) {
+    if (cached_settings.settings === '') {
+        generateSettings(request, function (err, settings) {
+            if (err) {
+                response.statusCode = 500;
+                response.end();
+            } else {
+                sendSettings.call(this, request, response, settings);
+            }
         });
+    } else {
+        sendSettings.call(this, request, response, cached_settings);
+    }
+}
+
+function sendSettings(request, response, settings) {
+    if (request.headers['if-none-match'] && request.headers['if-none-match'] === settings.hash) {
+        response.writeHead(304, 'Not Modified');
+        return response.end();
+    }
+
+    response.writeHead(200, {
+        'ETag': settings.hash,
+        'Content-Type': 'application/json'
     });
+    response.end(settings.settings);
 }