1 | var _ = require("underscore");
|
2 | var cluster = require("cluster");
|
3 |
|
4 | module.exports = function(env, cb){
|
5 |
|
6 | var config = env.config;
|
7 | var path = require("path");
|
8 | var fs = require("fs");
|
9 |
|
10 | var _ = require("underscore");
|
11 | var bulk = require("bulk-require");
|
12 |
|
13 | var actual_do;
|
14 |
|
15 | env.testSetup = [];
|
16 | env.stops = [];
|
17 |
|
18 | env.stop = function(cb){ env.helpers.chain(env.stops)(cb); };
|
19 |
|
20 | env.getCached = function(target){
|
21 | if(!target.__cached) { target.__cached = target.apply(env); }
|
22 | return target.__cached;
|
23 | };
|
24 |
|
25 | env.structureLoader = function(name, setup, cb, cached){
|
26 | var structureConfig = env.config.structures[name];
|
27 | if(!structureConfig.path && !structureConfig.instances) return cb();
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | if(structureConfig.path){
|
33 | var stagePath = path.join(env.config.rootDir, Array.isArray(structureConfig.path)?structureConfig.path[0]:structureConfig.path);
|
34 | if(fs.existsSync(stagePath)) {
|
35 | env.i[name] = bulk(stagePath, Array.isArray(structureConfig.path)?structureConfig.path[1]:["**/*.js", "**/*.coffee"]);
|
36 | }
|
37 | else{
|
38 | env.i[name] = {};
|
39 | }
|
40 | }
|
41 | else{
|
42 | env.i[name] = {};
|
43 | }
|
44 |
|
45 |
|
46 | var initializers = [], structureInit;
|
47 |
|
48 | env.i[name].do = env.i.do;
|
49 |
|
50 |
|
51 | if(env.i[name].index) {
|
52 | structureInit = env.i[name].index;
|
53 | delete env.i[name].index;
|
54 | }
|
55 |
|
56 | if(structureInit) structureInit.call(env, function(err, postinit){
|
57 | if(err) return cb(err);
|
58 | if(postinit) go(function(err){
|
59 | if(err) return cb(err);
|
60 | postinit(cb);
|
61 | });
|
62 | else go(cb);
|
63 | });
|
64 | else go(cb);
|
65 |
|
66 | function go(cb){
|
67 | env.helpers.traverse(env.i[name], function(target, nodeName, parent, path){
|
68 | if( nodeName === "do" || (nodeName === "stop" && parent === env.i[name].__run ) ) return;
|
69 | if(_.isFunction(target)) {
|
70 | var Node;
|
71 | if(setup) Node = setup(nodeName, cached? env.getCached(target) : target, path );
|
72 | else if (cached) Node = env.getCached(target);
|
73 | else Node = target;
|
74 |
|
75 | if(Node){
|
76 | parent[nodeName] = Node;
|
77 | if(Node.setupNode) initializers.push(Node.setupNode);
|
78 | }
|
79 | else delete parent[nodeName];
|
80 | }
|
81 | else target.do = actual_do;
|
82 | });
|
83 | env.i[name].__run = { stop: env.stop };
|
84 |
|
85 | if(initializers.length) env.helpers.chain(initializers)(cb, env);
|
86 | else cb();
|
87 | }
|
88 |
|
89 | }
|
90 |
|
91 | env.engines = {};
|
92 | env.i = {};
|
93 | env.classes = {};
|
94 |
|
95 |
|
96 | function findCbAndRespond(args, msg){
|
97 | var cb = _.last(args);
|
98 | if(_.isFunction(cb)) cb(msg)
|
99 | }
|
100 |
|
101 |
|
102 | var DO = function(address){
|
103 | var args = Array.prototype.slice.call(arguments);
|
104 | var address = args[0];
|
105 | var address_parts = address.split(".");
|
106 | var root = env.i[address_parts[0]];
|
107 | if(!root) return findCbAndRespond(args, "Can't find target: ", address);
|
108 | var last = _.last(address_parts);
|
109 | var context = env.helpers.resolve(env.i, address_parts.slice(0, -1).join("."));
|
110 | if(!context || !(_.isFunction(context[last]))) return findCbAndRespond(args, "Can't find target: "+address);
|
111 |
|
112 | if(context.parseArguments) args = context.parseArguments(args.slice(1));
|
113 | else args = args.slice(1);
|
114 | context[last].apply(context, args);
|
115 | };
|
116 |
|
117 |
|
118 | if(config.process_mode === "cluster"){
|
119 |
|
120 | var callbacks = {}, cb_index = 0;
|
121 | env.serializeCallback = function serializeCallback(fn){
|
122 | cb_index++;
|
123 | callbacks[cb_index] = fn;
|
124 | return cb_index;
|
125 | }
|
126 |
|
127 | env.runCallback = function runCallback(data){
|
128 | var fn = callbacks[data.run_cb[1]];
|
129 | if(fn) {
|
130 | fn.apply(global, data.args);
|
131 | if(!fn.isListener && !fn.isStream){
|
132 | env.dropCallback({drop_cb: data.run_cb});
|
133 | }
|
134 | }
|
135 | }
|
136 |
|
137 | env.dropCallback = function runCallback(data){
|
138 | var fn = callbacks[data.drop_cb[1]];
|
139 | if(fn) {
|
140 | delete callbacks[data.drop_cb[1]];
|
141 | }
|
142 | }
|
143 |
|
144 | var cluster = require("cluster");
|
145 | if(cluster.isMaster){
|
146 | require("./init/process/master.js")(env, cb);
|
147 | }
|
148 | else{
|
149 |
|
150 | env.deserializeCallback = function deserializeCallback(cb_data){
|
151 | var cb = Array.prototype.slice.call(cb_data);
|
152 | return function(){
|
153 | process.send({
|
154 | address: cb[0],
|
155 | run_cb: cb,
|
156 | args: Array.prototype.slice.call(arguments)
|
157 | });
|
158 | }
|
159 | }
|
160 |
|
161 | env.deserializeStream = function deserializeStream(stream_data){
|
162 | var stream = Array.prototype.slice.call(stream_data);
|
163 | var deserialized = function(){
|
164 | process.send({
|
165 | address: stream[0],
|
166 | run_cb: stream,
|
167 | args: Array.prototype.slice.call(arguments)
|
168 | });
|
169 | }
|
170 | deserialized.end = function(){ process.send({ address: stream[0], drop_cb: stream }); }
|
171 | return deserialized;
|
172 | }
|
173 |
|
174 | env.deserializeListener = function deserializeListener(listener_data){
|
175 | var listener = Array.prototype.slice.call(listener_data);
|
176 | var deserialized = function(){
|
177 | process.send({
|
178 | address: listener[0],
|
179 | run_cb: listener,
|
180 | args: Array.prototype.slice.call(arguments)
|
181 | });
|
182 | }
|
183 | deserialized.drop = function(){ process.send({ address: listener[0], drop_cb: listener }); };
|
184 | return deserialized;
|
185 | }
|
186 |
|
187 | actual_do = env.i.do;
|
188 |
|
189 | require("./init/process/worker.js")(env, cb);
|
190 | }
|
191 | }
|
192 | else {
|
193 |
|
194 | if(config.structures){
|
195 | _.each(config.structures, function(structure){
|
196 | if(structure.config){
|
197 | var partial_config = structure.config;
|
198 | _.extend(config, partial_config);
|
199 | delete structure.config;
|
200 | }
|
201 | });
|
202 | }
|
203 |
|
204 | actual_do = DO;
|
205 |
|
206 |
|
207 | var calls_cache = [];
|
208 | env.i.do = function(){
|
209 | calls_cache.push(arguments);
|
210 | }
|
211 | require("./init/process/single.js")(env, function(err){
|
212 | if(err) return cb(err);
|
213 |
|
214 | env.i.do = DO;
|
215 |
|
216 | for(var i=0;i<calls_cache.length; i++){
|
217 | DO.apply(env.i, calls_cache[i]);
|
218 | }
|
219 | delete calls_cache;
|
220 |
|
221 | cb(null, env);
|
222 | });
|
223 | }
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 | };
|