snowballhg
snowballhg

Reputation: 378

How to serialize NodeJS?

I'm exploring server side JavaScript with NodeJS and writing REST APIs with ExpressJS. My REST API is for configuring a device, much like configuring your home router. I would like to prevent parallel REST calls from attempting to configure the client without preventing multiple non-config requests.

Example API resources:

/api/config/network
/api/config/filesystem

In my example API, conceptually I'd like one client to be able to configure the network resource while another client configures the file system resource, while allowing other clients to query those resources.

I'm not sure how to accomplish this with JavaScripts asynchronous programming model. I come from a non-asynchronous programming background (multi-threaded C++). I am having trouble wrapping my head around this problem and wondering what ways one can solve this problem by hand, what if I had to write the plugin/module?.

Upvotes: 2

Views: 2590

Answers (1)

Peter Lyons
Peter Lyons

Reputation: 146084

When your express app gets a request to edit the config, add an item to an async.js queue configured with concurrency of 1. This will prevent > 1 concurrent attempt to edit the remote configuration. Pseudo code would be:

  • at app startup, define your updateNetworkConfig function
  • at app startup, create a queue of concurrency 1
    • var networkQueue = async.queue(updateNetworkConfig, 1);
  • REST comes in like PUT /api/config/network with the new config as the request body in JSON
  • Add an item to the queue, passing along the new config data
    • networkQueue.push(req.body.config);
    • (req.body provided by the bodyParser connect middleware)
  • Repeat that setup for each independent config: filesystem, etc

You'll need a bunch of other plumbing to deal with callbacks and notify the REST clients when their configuration has been saved. Up to you whether to queue up calls or reject new calls if the queue is not empty.

Since you insist on not learning and using the awesome async.js library that will increase your fluency with asynchronous programming and teach you valuable things, here's the deal. Use this thing called a variable.

var updatingNetwork = false;
app.put('/api/config/network', function (req, res) {
   if (updatingNetwork) {
       return res.status(409).send("Try later");
   }
   updatingNetwork = true;
   updateNetworkConfig(req.body.config, function (error) {
       updatingNetwork = false;
       if (error) {
           return res.status(500).send(error);
       }
       res.status(200).send("done");
   });   
});
  • When a request comes in, if updatingNetwork is true, you know there's already an update in process, either queue this one up or reject it.

Upvotes: 8

Related Questions