1 | var async = require('async');
|
2 | var assert = require('assert');
|
3 | var HappyThread = require('./HappyThread');
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | module.exports = function HappyThreadPool(config) {
|
14 | assert(!isNaN(config.size),
|
15 | "ArgumentError: HappyThreadPool requires a valid integer for its size, but got NaN."
|
16 | );
|
17 |
|
18 | assert(config.size > 0,
|
19 | "ArgumentError: HappyThreadPool requires a positive integer for its size " +
|
20 | ", but got {" + config.size + "}."
|
21 | );
|
22 |
|
23 | var threads = createThreads(config.size, config);
|
24 |
|
25 | return {
|
26 | size: config.size,
|
27 |
|
28 | start: function(done) {
|
29 | async.parallel(threads.filter(not(send('isOpen'))).map(get('open')), done);
|
30 | },
|
31 |
|
32 | configure: function(compilerOptions, done) {
|
33 | assert(!threads.some(not(send('isOpen'))),
|
34 | "ThreadPool must be started before attempting to configure it!"
|
35 | );
|
36 |
|
37 | async.parallel(threads.map(function(thread) {
|
38 | return function(callback) {
|
39 | thread.configure(compilerOptions, callback);
|
40 | }
|
41 | }), done);
|
42 | },
|
43 |
|
44 | isRunning: function() {
|
45 | return !threads.some(not(send('isOpen')));
|
46 | },
|
47 |
|
48 | stop: function() {
|
49 | threads.filter(send('isOpen')).map(send('close'));
|
50 | },
|
51 |
|
52 | get: RoundRobinThreadPool(threads)
|
53 | };
|
54 | }
|
55 |
|
56 | function createThreads(count, config, hooks) {
|
57 | var set = []
|
58 |
|
59 | for (var threadId = 0; threadId < count; ++threadId) {
|
60 | set.push(HappyThread(threadId, config, hooks));
|
61 | }
|
62 |
|
63 | return set;
|
64 | }
|
65 |
|
66 | function send(method) {
|
67 | return function(receiver) {
|
68 | return receiver[method].call(receiver);
|
69 | };
|
70 | }
|
71 |
|
72 | function get(attr) {
|
73 | return function(object) {
|
74 | return object[attr];
|
75 | };
|
76 | }
|
77 |
|
78 | function not(f) {
|
79 | return function(x) {
|
80 | return !f(x);
|
81 | };
|
82 | }
|
83 |
|
84 | function RoundRobinThreadPool(threads) {
|
85 | var lastThreadId = 0;
|
86 |
|
87 | return function getThread() {
|
88 | var threadId = lastThreadId;
|
89 |
|
90 | lastThreadId++;
|
91 |
|
92 | if (lastThreadId >= threads.length) {
|
93 | lastThreadId = 0;
|
94 | }
|
95 |
|
96 | return threads[threadId];
|
97 | }
|
98 | }
|