Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

processor改成并发执行 #63

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 80 additions & 67 deletions lib/processor/abstract.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
/**
* @file 构建处理器抽象类
* @author errorrik[[email protected]]
* zengjialuo[[email protected]]
*/

var edp = require( 'edp-core' );
var async = require('async');
var edp = require('edp-core');

/**
* 构建处理器抽象类
*
*
* @abstract
* @constructor
* @param {Object} options 初始化参数
*/
function AbstractProcessor( options ) {
for ( var key in options ) {
this[ key ] = options[ key ];
function AbstractProcessor(options) {
for (var key in options) {
this[key] = options[key];
}
this.log = edp.log;
}


/**
* 判断处理器是否忽略文件
*
*
* @param {FileInfo} file 文件信息对象
* @return {boolean} satisfy
*/
AbstractProcessor.prototype.isExclude = function ( file ) {
AbstractProcessor.prototype.isExclude = function (file) {
var satisfy = false;
var excludes = this.exclude instanceof Array
? this.exclude
: [];

excludes.forEach(
function ( path ) {
satisfy = satisfy || edp.path.satisfy( file.path, path, file.stat );
excludes.forEach(
function (path) {
satisfy = satisfy || edp.path.satisfy(file.path, path, file.stat);
}
);

Expand All @@ -42,18 +45,19 @@ AbstractProcessor.prototype.isExclude = function ( file ) {

/**
* 判断处理器是否包含文件。包含文件的优先级大于忽略文件
*
*
* @param {FileInfo} file 文件信息对象
* @return {boolean} satisfy
*/
AbstractProcessor.prototype.isInclude = function ( file ) {
AbstractProcessor.prototype.isInclude = function (file) {
var satisfy = false;
var includes = this.include instanceof Array
? this.include
: [];

includes.forEach(
function ( path ) {
satisfy = satisfy || edp.path.satisfy( file.path, path, file.stat );
includes.forEach(
function (path) {
satisfy = satisfy || edp.path.satisfy(file.path, path, file.stat);
}
);

Expand All @@ -62,28 +66,27 @@ AbstractProcessor.prototype.isInclude = function ( file ) {

/**
* 构建处理入口
*
*
* @param {ProcessContext} processContext 构建环境对象
* @param {Function} callback 处理完成回调函数
*/
AbstractProcessor.prototype.start = function ( processContext, callback ) {
AbstractProcessor.prototype.start = function (processContext, callback) {
var processor = this;
var start = Date.now();
this.beforeAll( processContext );
this.beforeAll(processContext);

var dots = ( require( 'os' ).platform() === 'darwin' ) ? '⋅⋅⋅' : '...';
var dots = (require('os').platform() === 'darwin') ? '⋅⋅⋅' : '...';

var me = this;
this._beforeLog = ' (' + (Date.now() - start ) + 'ms) ' + dots + ' ';
edp.log.write( this._beforeLog );
this._beforeLog = ' (' + (Date.now() - start) + 'ms) ' + dots + ' ';

this.processAll( processContext, finishProcessAll );
this.processAll(processContext, finishProcessAll);

function finishProcessAll() {
if ( processor.afterAll !== AbstractProcessor.prototype.afterAll ) {
if (processor.afterAll !== AbstractProcessor.prototype.afterAll) {
start = Date.now();
processor.afterAll( processContext );
edp.log.write( '%s ' + dots + ' (%sms)', me._doneLog, Date.now() - start );
processor.afterAll(processContext);
edp.log.write('%s ' + dots + ' (%sms)', me._doneLog, Date.now() - start);
}

callback();
Expand All @@ -92,21 +95,21 @@ AbstractProcessor.prototype.start = function ( processContext, callback ) {

/**
* 构建处理前的行为,选择要处理的文件
*
*
* @param {ProcessContext} processContext 构建环境对象
*/
AbstractProcessor.prototype.beforeAll = function ( processContext ) {
AbstractProcessor.prototype.beforeAll = function (processContext) {
var processor = this;
this.processFiles = Array.isArray( this.files )
? processContext.getFilesByPatterns( this.files )
this.processFiles = Array.isArray(this.files)
? processContext.getFilesByPatterns(this.files)
: processContext.getFiles().filter(
function ( file ) {
function (file) {
// processor处理文件
// 如果一个文件属于exclude,并且不属于include,则跳过处理
if ( typeof processor.isExclude === 'function'
&& processor.isExclude( file )
&& ( typeof processor.isInclude !== 'function'
|| !processor.isInclude( file )
if (typeof processor.isExclude === 'function'
&& processor.isExclude(file)
&& (typeof processor.isInclude !== 'function'
|| !processor.isInclude(file)
)
) {
return false;
Expand All @@ -119,11 +122,11 @@ AbstractProcessor.prototype.beforeAll = function ( processContext ) {

/**
* 处理后所有文件
*
*
* @param {ProcessContext} processContext 构建环境对象
* @param {Function} callback 处理完成回调函数
*/
AbstractProcessor.prototype.processAll = function ( processContext, callback ) {
AbstractProcessor.prototype.processAll = function (processContext, callback) {
var files = this.processFiles;
var fileIndex = 0;
var fileCount = files.length;
Expand All @@ -133,57 +136,67 @@ AbstractProcessor.prototype.processAll = function ( processContext, callback ) {
var me = this;
var beforeLog = this._beforeLog;

nextFile();
function nextFile() {
if ( fileIndex >= fileCount ) {
me._doneLog = require( 'util' ).format( '%s[%s/%s]: %s (%sms)',
beforeLog, fileCount, fileCount, 'Process done',
Date.now() - processStart );
edp.log.write( me._doneLog );
callback();
return;
}

var file = files[ fileIndex++ ];
function process(file, callback) {
var start = Date.now();

// processor处理需要保证异步性,否则可能因为深层次的层级调用产生不期望的结果
// 比如错误被n次调用前的try捕获到
function processFinished() {
edp.log.write('%s[%s/%s]: %s (%sms)', beforeLog, fileIndex, fileCount, file.path,
Date.now() - start );
setTimeout( nextFile, 1 );
}

processor.process(
file,
processContext,
processFinished
file,
processContext,
function () {
// error param was ignored

edp.log.write(
'%s[%s/%s]: %s (%sms)',
beforeLog,
++fileIndex,
fileCount,
file.path,
Date.now() - start
);
callback();
}
);
}

function processFinished() {
// error param was ignored

me._doneLog = require('util').format('%s[%s/%s]: %s (%sms)',
beforeLog, fileCount, fileCount, 'Process done',
Date.now() - processStart);
edp.log.write(me._doneLog);
callback();
return;
}

async.eachLimit(
files,
this.concurrent || 10,
process,
processFinished
);
};


/**
* 构建处理后的行为,默认啥都不干,特别的processor可以复写这个方法
*
*
* @virtual
* @param {ProcessContext} processContext 构建环境对象
*/
AbstractProcessor.prototype.afterAll = function ( processContext ) {};
AbstractProcessor.prototype.afterAll = function (processContext) {};

/**
* 构建处理单个文件
*
*
* @virtual
* @param {FileInfo} file 文件信息对象
* @param {ProcessContext} processContext 构建环境对象
* @param {Function} callback 处理完成回调函数
*/
AbstractProcessor.prototype.process = function (
file,
processContext,
callback
AbstractProcessor.prototype.process = function (
file,
processContext,
callback
) {
// do nothing in abstract class
callback();
Expand Down
Loading