From 209e22a995b03fa70bb2043f8c970c9bc6413b3e Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Tue, 1 May 2018 15:20:45 -0700 Subject: [PATCH 1/7] added hot reload functionallity --- lib/install.js | 35 +++++++++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/install.js b/lib/install.js index bc00769..46e81ef 100644 --- a/lib/install.js +++ b/lib/install.js @@ -6,6 +6,7 @@ var _ = require('lodash'); var assert = require('assert-plus'); var vasync = require('vasync'); var verror = require('verror'); +var Chain = require('restify/lib/chain'); /** * Install the enroute routes into the restify server. @@ -38,14 +39,40 @@ function install(opts, cb) { _.forEach(methods, function (src, method) { barrier.start(routeName + method); // resolve to the correct file - var sourceFile = path.resolve(opts.basePath, src.source); + var sourceFile = path.resolve(opts.basePath, src.source); var route; - + try { route = { name: routeName, method: method, - func: require(sourceFile) + func: process.env.HOT_RELOAD === 'true' + ? function(req, resp, callback) { + if(typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { + //Delete code loaded from a specific base dir + Object.keys(require.cache).forEach(function (k) { + if(k.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { + delete require.cache[k]; + } + }); + } else { + //Delete all cached entries + Object.keys(require.cache).forEach(function (k) { + delete require.cache[k]; + }); + } + + var handlers = require(sourceFile); + + //Re-use restify chain logic to handle request. + var chain = new Chain(); + handlers.forEach(function (handler) { + chain.add(handler); + }); + + chain.run(req, resp, callback); + } + : require(sourceFile) }; } catch (e) { return cb1(new verror.VError({ @@ -78,7 +105,7 @@ function install(opts, cb) { var routePath = typeof route.name === 'string' && route.name[0] === '/' ? route.name - : '/' + route.name; + : '/' + route.name; opts.server[route.method](routePath, route.func); }); diff --git a/package.json b/package.json index dc25362..6700f0a 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "jscs": "^3.0.7", "mocha": "^3.1.2", "nsp": "^2.6.2", - "restify": "^7.0.0", "restify-clients": "^1.4.0", "uuid": "^2.0.3" }, @@ -45,6 +44,7 @@ "ajv": "^4.8.0", "assert-plus": "^1.0.0", "lodash": "^4.16.4", + "restify": "^7.0.0", "vasync": "^1.6.4", "verror": "^1.6.0" } From 829038d627a703e6bb142d261fa1bd3e10a42fee Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Tue, 1 May 2018 16:48:29 -0700 Subject: [PATCH 2/7] renaming variable for readability --- lib/install.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/install.js b/lib/install.js index 46e81ef..6faf1bb 100644 --- a/lib/install.js +++ b/lib/install.js @@ -50,20 +50,20 @@ function install(opts, cb) { ? function(req, resp, callback) { if(typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { //Delete code loaded from a specific base dir - Object.keys(require.cache).forEach(function (k) { - if(k.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { - delete require.cache[k]; + Object.keys(require.cache).forEach(function (cacheKey) { + if(cacheKey.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { + delete require.cache[cacheKey]; } }); } else { //Delete all cached entries - Object.keys(require.cache).forEach(function (k) { - delete require.cache[k]; + Object.keys(require.cache).forEach(function (cacheKey) { + delete require.cache[cacheKey]; }); } var handlers = require(sourceFile); - + //Re-use restify chain logic to handle request. var chain = new Chain(); handlers.forEach(function (handler) { From f60b2cfb424a7fff903640b90ed4219a3ae4a21d Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Thu, 3 May 2018 10:51:59 -0700 Subject: [PATCH 3/7] extra logging --- lib/install.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/install.js b/lib/install.js index 6faf1bb..7d38988 100644 --- a/lib/install.js +++ b/lib/install.js @@ -41,7 +41,7 @@ function install(opts, cb) { // resolve to the correct file var sourceFile = path.resolve(opts.basePath, src.source); var route; - + console.log("Installing routes. Hot reloading: " + process.env.HOT_RELOAD); try { route = { name: routeName, @@ -53,12 +53,14 @@ function install(opts, cb) { Object.keys(require.cache).forEach(function (cacheKey) { if(cacheKey.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { delete require.cache[cacheKey]; + console.log("Invalidated cache for " + cacheKey); } }); } else { //Delete all cached entries Object.keys(require.cache).forEach(function (cacheKey) { delete require.cache[cacheKey]; + console.log("Invalidated cache for " + cacheKey); }); } From d7dabdcbc49b23d1626c3b755614d57b483c8bc5 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Mon, 7 May 2018 15:45:50 -0700 Subject: [PATCH 4/7] Flatten handlers array --- lib/install.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/install.js b/lib/install.js index 7d38988..fb58ec8 100644 --- a/lib/install.js +++ b/lib/install.js @@ -64,14 +64,19 @@ function install(opts, cb) { }); } - var handlers = require(sourceFile); - //Re-use restify chain logic to handle request. var chain = new Chain(); - handlers.forEach(function (handler) { - chain.add(handler); - }); - + + var handlers = require(sourceFile); + if(_.isArray(handlers)) { + handlers = _.flattenDeep(handlers); + handlers.forEach(function (handler) { + chain.add(handler); + }); + } else { + chain.add(handlers); + } + chain.run(req, resp, callback); } : require(sourceFile) From 38e540a8897a74c2ebb76d4db76f86653327372d Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Tue, 15 May 2018 15:01:59 -0700 Subject: [PATCH 5/7] using composer function to build handler chain --- lib/install.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/install.js b/lib/install.js index fb58ec8..186679f 100644 --- a/lib/install.js +++ b/lib/install.js @@ -6,7 +6,7 @@ var _ = require('lodash'); var assert = require('assert-plus'); var vasync = require('vasync'); var verror = require('verror'); -var Chain = require('restify/lib/chain'); +var chainComposer = require('restify').helpers.chainComposer; /** * Install the enroute routes into the restify server. @@ -64,22 +64,19 @@ function install(opts, cb) { }); } - //Re-use restify chain logic to handle request. - var chain = new Chain(); - - var handlers = require(sourceFile); - if(_.isArray(handlers)) { - handlers = _.flattenDeep(handlers); - handlers.forEach(function (handler) { - chain.add(handler); - }); - } else { - chain.add(handlers); - } - chain.run(req, resp, callback); + try { + var handlers = require(sourceFile); + var handlerChain = chainComposer(handlers); + + handlerChain(req, resp, callback); + } catch (e) { + console.error("Uncaught error in route:"); + console.error(e); + callback(e); + } } - : require(sourceFile) + : require(sourceFile) }; } catch (e) { return cb1(new verror.VError({ From ba3f75f91a716060f29c5ef9c421005a4be884e8 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Wed, 16 May 2018 14:34:04 -0700 Subject: [PATCH 6/7] now using a released version of restify --- lib/install.js | 11 ++++------- package.json | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/install.js b/lib/install.js index 186679f..92ef45c 100644 --- a/lib/install.js +++ b/lib/install.js @@ -6,7 +6,7 @@ var _ = require('lodash'); var assert = require('assert-plus'); var vasync = require('vasync'); var verror = require('verror'); -var chainComposer = require('restify').helpers.chainComposer; +var compose = require('restify').helpers.compose; /** * Install the enroute routes into the restify server. @@ -39,7 +39,7 @@ function install(opts, cb) { _.forEach(methods, function (src, method) { barrier.start(routeName + method); // resolve to the correct file - var sourceFile = path.resolve(opts.basePath, src.source); + var sourceFile = path.resolve(opts.basePath, src.source); var route; console.log("Installing routes. Hot reloading: " + process.env.HOT_RELOAD); try { @@ -48,26 +48,23 @@ function install(opts, cb) { method: method, func: process.env.HOT_RELOAD === 'true' ? function(req, resp, callback) { - if(typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { + if (typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { //Delete code loaded from a specific base dir Object.keys(require.cache).forEach(function (cacheKey) { if(cacheKey.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { delete require.cache[cacheKey]; - console.log("Invalidated cache for " + cacheKey); } }); } else { //Delete all cached entries Object.keys(require.cache).forEach(function (cacheKey) { delete require.cache[cacheKey]; - console.log("Invalidated cache for " + cacheKey); }); } - try { var handlers = require(sourceFile); - var handlerChain = chainComposer(handlers); + var handlerChain = compose(handlers); handlerChain(req, resp, callback); } catch (e) { diff --git a/package.json b/package.json index 6700f0a..50f65e8 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "ajv": "^4.8.0", "assert-plus": "^1.0.0", "lodash": "^4.16.4", - "restify": "^7.0.0", + "restify": "^7.2.0", "vasync": "^1.6.4", "verror": "^1.6.0" } From cb3ca384bbee9db2ea1b07039c694b22c1851948 Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Thu, 17 May 2018 13:37:21 -0700 Subject: [PATCH 7/7] using bunyan for logging and cleaned up code --- lib/install.js | 72 +++++++++++++++++++++++++++++++------------------- package.json | 1 + 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/lib/install.js b/lib/install.js index 92ef45c..7d68b37 100644 --- a/lib/install.js +++ b/lib/install.js @@ -7,6 +7,10 @@ var assert = require('assert-plus'); var vasync = require('vasync'); var verror = require('verror'); var compose = require('restify').helpers.compose; +var bunyan = require('bunyan'); +var LOG = bunyan.createLogger({name: 'enroute'}); + + /** * Install the enroute routes into the restify server. @@ -33,6 +37,16 @@ function install(opts, cb) { return cb1(); }); + if (process.env.HOT_RELOAD) { + if (typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { + LOG.info( + 'Hot reloading of routes is enabled for base dir' + + process.env.HOT_RELOAD_BASEDIR); + } else { + LOG.info('Hot reloading of routes is enabled.'); + } + } + // go through each of the route names _.forEach(opts.enroute.routes, function (methods, routeName) { // go through each of the HTTP methods @@ -41,37 +55,14 @@ function install(opts, cb) { // resolve to the correct file var sourceFile = path.resolve(opts.basePath, src.source); var route; - console.log("Installing routes. Hot reloading: " + process.env.HOT_RELOAD); + try { route = { name: routeName, method: method, func: process.env.HOT_RELOAD === 'true' - ? function(req, resp, callback) { - if (typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { - //Delete code loaded from a specific base dir - Object.keys(require.cache).forEach(function (cacheKey) { - if(cacheKey.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { - delete require.cache[cacheKey]; - } - }); - } else { - //Delete all cached entries - Object.keys(require.cache).forEach(function (cacheKey) { - delete require.cache[cacheKey]; - }); - } - - try { - var handlers = require(sourceFile); - var handlerChain = compose(handlers); - - handlerChain(req, resp, callback); - } catch (e) { - console.error("Uncaught error in route:"); - console.error(e); - callback(e); - } + ? function (req, resp, callback) { + reloadProxy(sourceFile, req, resp, callback); } : require(sourceFile) }; @@ -106,7 +97,7 @@ function install(opts, cb) { var routePath = typeof route.name === 'string' && route.name[0] === '/' ? route.name - : '/' + route.name; + : '/' + route.name; opts.server[route.method](routePath, route.func); }); @@ -117,4 +108,31 @@ function install(opts, cb) { }); } +function reloadProxy(sourceFile, req, resp, callback) { + if (typeof process.env.HOT_RELOAD_BASEDIR !== 'undefined') { + //Delete code loaded from a specific base dir + Object.keys(require.cache).forEach(function (cacheKey) { + if (cacheKey.indexOf(process.env.HOT_RELOAD_BASEDIR) !== -1) { + delete require.cache[cacheKey]; + } + }); + } else { + //Delete all cached entries + Object.keys(require.cache).forEach(function (cacheKey) { + delete require.cache[cacheKey]; + }); + } + + try { + var handlers = require(sourceFile); + var handlerChain = compose(handlers); + + handlerChain(req, resp, callback); + } catch (e) { + LOG.error('Uncaught error in route:'); + LOG.error(e); + callback(e); + } +} + module.exports = install; diff --git a/package.json b/package.json index 50f65e8..3a36987 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "dependencies": { "ajv": "^4.8.0", "assert-plus": "^1.0.0", + "bunyan": "^1.8.12", "lodash": "^4.16.4", "restify": "^7.2.0", "vasync": "^1.6.4",