Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic dropping of handlers in restify

Context

I am trying to build a dynamic server with restify (2.6.2) where services are to be installed and uninstalled once the server is started. I realized this can be seen as something odd but it has sense in the context of a DSL oriented project. To achieve this goal I have implemented the following functions:

var install = function (path, method, handler) { 
    var id = server[method](path, function (request, response) { // [1]
        handler (request, response);
    });
    return id;
} 
var uninstall = function (id) { 
    delete server.routes[id]; // [2]
}

The install function, installs a handler in the route specified by a path and a method name [1]. The uninstall function, uninstall the handler by dropping it from routes [2]. This capabilities are exposed as services by the following code:

var db = ...
var server = restify.createServer ()
    .use (restify.bodyParser ({ mapParams: false }))
    .use (restify.queryParser ())
    .use (restify.fullResponse ());
service.post ('/services', function (request, response) {
   var path    = request.body.path;
   var method  = request.body.method;
   var handler = createHandler (request.body.dsl) // off-topic
   var id = install (path, method, handler)
   db.save (path, method, id); // [3]
});
service.del ('/services', function (request, response) {
   var path   = request.body.path;
   var method = request.body.method;
   var id     = db.load (path, method); // [4]
   uninstall (id);
});

In post method [3], a handler is obtained from body (it is off-topic how this is undertaken) and a service is installed storing the returned id in a database. The del method [4], retrieves the id from the database and invokes the uninstall function.

Problem

This code has been unit-tested and it works properly but a malfunction is reached when I try to execute an install/uninstall sequence like the following one. In this example, please suppose that the body of all requests contains the same path, http verb and proper content to build a correct handler:

/*
post: /services : Installed          -> ok
del:  /services : Resource not found -> ok
post: /services : Resource not found -> Error :(
*/

In the first install, handler is executed when resource is acceded via path and verb. The uninstall request is correctly fulfilled because a Resource not found message is obtained when path is visited on verb. Nevertheless, when the same body is installed secondly in the server, a Resource not found is returned when path is acceded on verb.

I suppose that the error is in [2] because, may be, I am not using the correct unregister strategy for restify.

Question

How can be effectively dropped handlers from restify once the server is started?

like image 927
Javier Vélez Avatar asked Jun 15 '15 03:06

Javier Vélez


1 Answers

After looking at the restify source I found the following, which you may want to try instead of simply 'delete' (https://github.com/restify/node-restify/blob/master/lib/server.js).

/*
* Removes a route from the server.
* You pass in the route 'blob' you got from a mount call.
* @public
* @function rm
* @throws   {TypeError} on bad input.
* @param    {String}    route the route name.
* @returns  {Boolean}         true if route was removed, false if not.
*/
Server.prototype.rm = function rm(route) {
    var r = this.router.unmount(route);

    if (r && this.routes[r]) {
        delete this.routes[r];
    }

    return (r);
};
like image 198
HeadCode Avatar answered Oct 29 '22 07:10

HeadCode