app.js
// start app
app.start();
lib/application.js
/**
* Start application. It would load the default components and start all the loaded components.
*
* @param {Function} cb callback function
*
* @memberOf Application
*/
Application.start = function(cb) {
if(this.state > STATE_INITED) {
utils.invokeCallback(cb, new Error('application has already start.'));
return;
}
this.loadDefaultComponents();
var self = this;
this._optComponents('start', function(err) {
self.state = STATE_START;
utils.invokeCallback(cb, err);
});
};
Application状态注释,当application进入初始化的时候调用 loadDefaultComponents 和 _optComponents 等
/**
* Application states
*/
var STATE_INITED = 1; // app has inited
var STATE_START = 2; // app start
var STATE_STARTED = 3; // app has started
var STATE_STOPED = 4; // app has stoped
加载默认的application模块
/**
* Load default components for application.
*
* @api private
*/
Application.loadDefaultComponents = function(){
var pomelo = require('./pomelo');
if (this.serverType === 'master') {
this.load(pomelo.master, this.get('masterConfig'));
} else {
this.load(pomelo.proxy, this.get('proxyConfig'));
if(this.getServerById(this.get('serverId')).port) {
this.load(pomelo.remote, this.get('remoteConfig'));
}
if(this.isFrontend()) {
this.load(pomelo.connection, this.get('connectionConfig'));
this.load(pomelo.connector, this.get('connectorConfig'));
this.load(pomelo.session, this.get('sessionConfig'));
} else {
this.load(pomelo.localSession, this.get('localSessionConfig'));
}
this.load(pomelo.channel, this.get('channelConfig'));
this.load(pomelo.server, this.get('serverConfig'));
}
this.load(pomelo.monitor, this);
};
根据配置文件来加载对应的服务器,让我们看看load函数
/**
* Load component
*
* @param {String} name (optional) name of the component
* @param {Object} component component instance or factory function of the component
* @param {[type]} opts (optional) construct parameters for the factory function
* @return {Object} app instance for chain invoke
*
* @memberOf Application
*/
Application.load = function(name, component, opts) {
if(typeof name !== 'string') {
opts = component;
component = name;
name = null;
if(typeof component.name === 'string') { //确认参数是名字还是函数
name = component.name;
}
}
if(typeof component === 'function') { //确认是函数后,执行其对应的构造函数,如果存入的参数是Mater,那就相当于执行master(this.opts) -> this.master = new Master(app)
component = component(this, opts);
}
if(!component) {
// maybe some component no need to join the components management
logger.info('load empty component');
return this;
}
if(!name && typeof component.name === 'string') {
name = component.name;
}
if(name && this.components[name]) {
// ignore duplicat component
logger.warn('ignore duplicate component: %j', name);
return;
}
this.loaded.push(component);
if(name) {
// components with a name would get by name throught app.components later.
this.components[name] = component; //执行完模块的构造函数后,将实例对象存放到components里,如master,即new Master(app)返回的实例
}
return this;
};
初始化默认加载模块的列表汇总
- master: master组件主要负责启动master服务器。
- monitor: monitor组件主要负责启动各个服务器的monitor服务,该服务负责收集服务器的信息并定期向master进行消息推送,保持master与各个服务器的心跳连接。
- proxy: proxy组件主要负责生成服务器rpc客户端,由于系统中存在多个服务器进程,不同服务器进程之间相互通信需要通过rpc调用(master服务器除外)。
- handler:handler组件主要负责加载前端服务器中的handler目录下的文件。
- filter: filter组件主要负责加载服务器请求的filter服务,包括rpc调用前的filter及rpc调用后的filter。
- remote: remote组件主要负责加载后端服务器的服务并生成服务器rpc服务端。
- server:server组件主要负责启动所有服务器的用户请求处理服务。
- connector: connector组件主要负责启动前端服务器的session服务和接收用户请求。
- sync: sync组件主要负责启动数据同步模块并对外提供数据同步功能。
- connection: connection组件主要负责启动用户连接信息的统计服务。
从已加载模块里面,批量执行对应模块的方法,根据上面的代码,传入的参数是‘start',即每一个模块都执行start,如master,即执行master.start()
/**
* Apply command to loaded components.
* This method would invoke the component {method} in series.
* Any component {method} return err, it would return err directly.
*
* @param {String} method component lifecycle method name, such as: start, afterStart, stop
* @param {Function} cb
* @api private
*/
Application._optComponents = function(method, cb) {
var i = 0;
async.forEachSeries(this.loaded, function(comp, done) { //async 异步里面同步执行模块,forEachSeries,即逐个模块执行start,同步执行,如master,即执行master.start
i++;
if(typeof comp[method] === 'function') { //判断是否存在method里的方法,如果存在,即执行
comp[method](done);
} else {
done();
}
}, function(err) {
if(err) {
logger.error('[pomelo application] fail to operate component, method:%s, err:' + err.stack, method);
}
cb(err);
});
};
这篇就介绍完毕,通过loadDefaultComponents 函数加载默认模块,master是服务器最基本的模块,下篇我们将从 master.start 开始分析