Skip to content

Instantly share code, notes, and snippets.

@xat
Last active December 14, 2015 01:39
Show Gist options
  • Save xat/5008385 to your computer and use it in GitHub Desktop.
Save xat/5008385 to your computer and use it in GitHub Desktop.
A simple demonstrantion of a sheduler done in Node.JS. Tasks can be split up in multiple Queues. Tasks can be marked as "exclusive" if they should not be run concurrent with other tasks.
var http = require('http'),
async = require('async'),
queueBuilder,
taskBuilder,
counter,
maxConcurrent = Number.POSITIVE_INFINITY,
debug = true,
queues = {},
tasks = {};
// Some Helper functions, used for debugging / logging:
counter = (function() {
var current = 0;
return function() {
return ++current;
}
})();
debugTaskBuilder = function(task, debugBefore, debugAfter) {
return function(cb) {
console.log(debugBefore);
task.call(this, function() {
console.log(debugAfter);
cb();
});
};
};
// Tasks which get executed by workers
// within the Queue
tasks.fakeTimeout = function(cb) {
setTimeout(function() {
cb();
}, Math.floor((Math.random()*10000)+1));
};
tasks.httpRequest = function(cb) {
http.get("http://www.spiegel.de", function(res) {
cb();
});
};
tasks.concurrencyOne = function(cb) {
this.concurrency = 1;
cb();
};
tasks.concurrencyMax = function(cb) {
this.concurrency = maxConcurrent;
cb();
};
// Queue factory
queueBuilder = function() {
var queue = async.queue(function(task, cb) {
task.call(queue, function() {
cb();
});
}, maxConcurrent);
return queue;
};
// Build Queues
queues.cook = queueBuilder();
queues.wash = queueBuilder();
// Adding Tasks:
// Normal: http://127.0.0.1:9999/?queue=wash
// Exclusive: http://127.0.0.1:9999/?queue=wash&exclusive=1
// Specific Task: http://127.0.0.1:9999/?queue=wash&task=httpRequest
http.createServer(function(req, res) {
var query = require('url').parse(req.url,true).query;
if (!(query.queue && queues[query.queue])) {
res.end('0');
return;
}
var id = counter(),
queue = queues[query.queue],
task = (query.task && tasks[query.task])?query.task:'fakeTimeout';
if (query.exclusive == 1) {
// Set Concurreny to 1 before running
// an exclusive task
queue.push(tasks.concurrencyOne);
// Add Exclusive Task
if (debug) {
queue.push(debugTaskBuilder(tasks[task],
'Start exclusive Task #'+id+' in Queue ' + query.queue,
'End exclusive Task #'+id
));
} else {
queue.push(tasks[task]);
}
// Set Concurrency back to maxConcurrent
queue.push(tasks.concurrencyMax);
} else {
// Add Normal Task
if (debug) {
queue.push(debugTaskBuilder(tasks[task],
'Start Task #'+id+' in Queue ' + query.queue,
'End Task #'+id
));
} else {
queue.push(tasks[task]);
}
}
res.end('1');
}).listen(9999);
@xat
Copy link
Author

xat commented Feb 21, 2013

AB Ergebnis. 1 Millionen Requests / 100 Parallel:

simon@simon-desktop:~/Arbeitsfläche/sheduler$ ab -n 1000000 -c 100 http://127.0.0.1:9999/?queue=wash
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Completed 1000000 requests
Finished 1000000 requests


Server Software:        
Server Hostname:        127.0.0.1
Server Port:            9999

Document Path:          /?queue=wash
Document Length:        1 bytes

Concurrency Level:      100
Time taken for tests:   160.431 seconds
Complete requests:      1000000
Failed requests:        0
Write errors:           0
Total transferred:      76000000 bytes
HTML transferred:       1000000 bytes
Requests per second:    6233.19 [#/sec] (mean)
Time per request:       16.043 [ms] (mean)
Time per request:       0.160 [ms] (mean, across all concurrent requests)
Transfer rate:          462.62 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       4
Processing:     1   16   8.3     16      54
Waiting:        1   16   8.3     15      54
Total:          2   16   8.3     16      54

Percentage of the requests served within a certain time (ms)
  50%     16
  66%     20
  75%     22
  80%     23
  90%     27
  95%     31
  98%     34
  99%     37
 100%     54 (longest request)
simon@simon-desktop:~/Arbeitsfläche/sheduler$ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment