var i = 0; var max = 10; // Nb loops var delay = 1000; // ms between loops var completed = false; var workerID, watcherID; var performLoop = function(clientChannel) { console.log('... Loop # ' + i); if (++i < max) { workerID = setTimeout(function() { performLoop(clientChannel); }, delay); // There is a wait here, just to waste time. } else { completed = true; clientChannel("End of loop, clearing the watcher."); clearTimeout(watcherID); } }; var workAndWatch = function(worker, timeout, cb) { console.log("Starting Worker"); // The worker setTimeout(function() { worker(cb); }, 0); console.log("Starting Watcher"); // The watcher watcherID = setTimeout(function() { if (!completed) { cb("Killing the lazy worker."); clearTimeout(workerID); } }, timeout); console.log("Watcher & worker started."); }; var callback = function(mess) { console.log(mess); }; workAndWatch(performLoop, 10000, callback);The work to do is describe in the function performLoop.
What we want here, is to make sure whatever runs will not take more than a given amount of time.
This amount of time is given as the second parameter of the function workAndWatch.
workAndWatch(performLoop, 5000, callback);I use node.js to run this script.
Let's give a 5 seconds timeout:
Prompt> node hang.detection.js Starting Worker Starting Watcher Watcher & worker started. ... Loop # 0 ... Loop # 1 ... Loop # 2 ... Loop # 3 ... Loop # 4 Killing the lazy worker.And now, let's give it 10 seconds:
workAndWatch(performLoop, 10000, callback);
Prompt> node hang.detection.js Starting Worker Starting Watcher Watcher & worker started. ... Loop # 0 ... Loop # 1 ... Loop # 2 ... Loop # 3 ... Loop # 4 ... Loop # 5 ... Loop # 6 ... Loop # 7 ... Loop # 8 ... Loop # 9 End of loop, clearing the watcher.It actually behaves like if we were dealing with two threads. The cool thing is that we don't need to worry about any kind of synchronization... ;0)