Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update server's content without restarting it? (node.js)

So I have a simple node.js server which serves only dynamic content:

// app.js
var app = require('express')();

app.get('/message/:poster', function(request, response) {
    response.writeHeader(200, {'content-type': 'text/html'});

    // some database queries

    response.end(""+
    "<!DOCTYPE html>"+
    "<html>"+
        "<head>"+
            "<title>messages of "+request.params.poster+"</title>"+
            "<script src='http://example.com/script.js'></script>"+
            "<link rel='stylesheet' href='http://example.com/style.css'>"+
        "</head>"+
        "<body>"+
        "" // and so on
    );
})

app.listen(2345);

Now, suppose I want to update my HTML.
And suppose further that I don't want to restart the server.
Is there a way of achieving this?

I tried exporting the part to send to an external file like:

// lib.js
module.exports.message = function(request, response) {
    response.writeHeader(200, {'content-type': 'text/html'})

    //some database queries

    response.end(""+
    "<!DOCTYPE html>"+
    "<html>"+
        "<head>"+
            "<title>messages of "+request.params.poster+"</title>"+
            "<script src='http://example.com/script.js></script>"+
            "<link rel='stylesheet' href='http://example.com/style.css'>"+
        "</head>"+
        "<body>"+
        "" //and so on
    );
}

and

// app.js
var app = require('express')();

app.get('/message/:poster', require('./lib.js').message)

app.listen(2345);

And it works but if I update lib.js it doesn't update. It seems to be making a copy of that function.
Then I tried

// app.js
var app = require('express')();

app.get('/message/:poster', function(request, response) {
    require('./lib.js').message(request, response);
})

app.listen(2345);

But this doesn't update either.
Seems like the function gets cached and reused all the time(once I start the server). I dare say that there must be a way to set it so that it either revalidates the function each time(checking if the file containing it changed) and if so updates its cache, or we can set it to update the function each n amount of time, or even better, since we're in node, having an event listener for changes to the files containing the function and as the function changes, event fires and the function in cache gets updated.
So how do we get one of the above behaviors? Or something else? I know to restart a server may take only 100ms but restarting it would interrupt all the currently active websockets, which is not an option.
NOTE: I don't want to use any templating languages like jade, ejc etc.

like image 430
Core_dumped Avatar asked Feb 15 '15 09:02

Core_dumped


2 Answers

By requiring a module its module.exports is cached for all future calls to require. You can programmatically empty the cache: http://nodejs.org/docs/latest/api/globals.html#globals_require_cache. If you additionally want to do it upon a file change you can use fs.watch: http://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener.

like image 153
artur grzesiak Avatar answered Oct 24 '22 08:10

artur grzesiak


If you dont want to loose any request in production - just gracefull restart your app using PM2, Forever, etc. If you want to automatic apply your changes in development - use Nodemon. I dont know any other reason why you dont like to restart app.

like image 1
Daniel Avatar answered Oct 24 '22 08:10

Daniel