UNPKG

7.08 kBJavaScriptView Raw
1'use strict';
2
3/**
4 * Module dependencies.
5 */
6require('./init');
7
8var cluster = require('cluster'),
9 domain = require('domain'),
10 fs = require('fs'),
11 http = require('http'),
12 express = require('express'),
13 cookieParser = require('cookie-parser'),
14 session = require('express-session'),
15 errorHandler = require('express-error-handler'),
16 Framework = require('./framework'),
17 Initializer = require('./initializer'),
18 InitializerServer = require('./initializer-server')
19;
20
21/**
22 * Expose `createApplication`.
23 */
24module.exports = createApplication;
25
26/**
27 * Create an express application and wrap it
28 * in a danf application.
29 *
30 * @param {object} configuration The danf configuration.
31 * @param {object} serverContext The server application context.
32 * @param {object} clientContext The client application context.
33 * @param {function} callback An optional callback to process before to listen to requests.
34 * @api public
35 */
36function createApplication(configuration, serverContext, clientContext, callback) {
37 // Handle context.
38 var args = process.argv.slice(2),
39 formatContext = function(context, defaultContext) {
40 if (!context) {
41 context = defaultContext;
42 } else {
43 Object.checkType(context, 'object');
44
45 for (var name in defaultContext) {
46 if (undefined === context[name]) {
47 context[name] = defaultContext[name];
48 }
49 }
50 }
51
52 for (var arg in args) {
53 var argParts = args.indexOf('=');
54
55 if (argParts.length >= 2) {
56 var name = argParts.shift(),
57 value = argParts.join('')
58 ;
59
60 context[name] = value;
61 }
62 }
63
64 return context;
65 }
66 ;
67
68 var context = formatContext(
69 serverContext,
70 {
71 app: 'main',
72 environment: 'dev',
73 debug: true,
74 listen: true,
75 port: 3080,
76 workers: 1,
77 secret: 'bad secret'
78 }
79 ),
80 clientContext = formatContext(
81 clientContext,
82 {
83 app: 'main',
84 environment: 'dev',
85 debug: true,
86 modules: [
87 'manipulation',
88 'configuration',
89 'object',
90 'dependency-injection',
91 'event',
92 'http',
93 'vendor',
94 'ajax-app'
95 ]
96 }
97 )
98 ;
99
100 // Process master.
101 if (cluster.isMaster && 'test' !== context.environment) {
102 var cpuCount = require('os').cpus().length,
103 workersNumber = context.workers >= 1
104 ? context.workers
105 : cpuCount + context.workers
106 ;
107
108 workersNumber = Math.min(Math.max(workersNumber, 1), cpuCount);
109
110 for (var i = 0; i < workersNumber; i++) {
111 cluster.fork();
112 }
113 // Process workers.
114 } else {
115 if (cluster.worker) {
116 var workerId = cluster.worker.id;
117
118 context.worker = workerId;
119
120 if (!context.silent) {
121 console.log('Worker "{0}" processing.'.format(workerId));
122 }
123 }
124
125 var app = express();
126
127 // Use.
128 app.useBeforeRouting = function () {
129 this.use(function(req, res, next) {
130 var dom = domain.create();
131
132 domain.active = dom;
133 dom.add(req);
134 dom.add(res);
135
136 dom.on('error', function(err) {
137 req.next(err);
138 });
139 res.on('end', function() {
140 dom.dispose();
141 });
142
143 dom.run(next);
144 });
145
146 this.use(cookieParser());
147 this.use(session({
148 secret: context.secret,
149 cookie: {},
150 resave: true,
151 saveUninitialized: true
152 }));
153 };
154 app.useAfterRouting = function () {
155 };
156
157 // Create.
158 app.create = function() {
159 this.context = context;
160 this.clientContext = clientContext;
161
162 this.useBeforeRouting();
163
164 // Build framework.
165 var framework = new Framework(),
166 initializer = new Initializer(),
167 initializerServer = new InitializerServer()
168 ;
169
170 framework.addInitializer(initializer);
171 framework.addInitializer(initializerServer);
172 framework.set('danf:app', this);
173 framework.build(configuration, context);
174
175 this.servicesContainer = framework.objectsContainer;
176
177 this.useAfterRouting();
178
179 if (callback) {
180 Object.checkType(callback, 'function');
181
182 callback(this);
183 }
184
185 if (context.listen) {
186 this.listen(context.silent);
187 }
188 };
189
190 // Override listen.
191 app.listen = function(silent) {
192 var server = http.createServer(this)
193
194 server.listen(this.context.port);
195 this.use(errorHandler({server: server}));
196
197 if (!silent) {
198 console.log('Server running at "http://127.0.0.1:{0}/"'.format(this.context.port));
199 }
200 };
201
202 /**
203 * Get/set the context of the application.
204 *
205 * @return {object}
206 * @api public
207 */
208 Object.defineProperty(app, 'context', {
209 get: function() { return this._context; },
210 set: function(context) { this._context = context; }
211 });
212
213 /**
214 * Get/set the client context of the application.
215 *
216 * @return {object}
217 * @api public
218 */
219 Object.defineProperty(app, 'clientContext', {
220 get: function() { return this._clientContext; },
221 set: function(clientContext) { this._clientContext = clientContext; }
222 });
223
224 /**
225 * Get/set the services container.
226 *
227 * @return {object}
228 * @api public
229 */
230 Object.defineProperty(app, 'servicesContainer', {
231 get: function() { return this._servicesContainer; },
232 set: function(servicesContainer) { this._servicesContainer = servicesContainer; }
233 });
234
235 app.create();
236
237 return app;
238 }
239
240 cluster.on('exit', function (worker) {
241 if (!context.silent) {
242 console.log('Worker "{0}" died.'.format(worker.id));
243 }
244
245 cluster.fork();
246 });
247};
\No newline at end of file