ee-core 2.0.3 → 2.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/bin/tools.js +4 -0
  2. package/config/config.default.js +9 -0
  3. package/const/channel.js +10 -1
  4. package/core/lib/ee.js +1 -1
  5. package/core/lib/loader/file_loader.js +2 -2
  6. package/core/lib/loader/mixin/config.js +1 -1
  7. package/core/lib/utils/index.js +1 -1
  8. package/ee/eeApp.js +8 -7
  9. package/exception/index.js +40 -12
  10. package/httpclient/index.js +4 -12
  11. package/index.js +1 -1
  12. package/jobs/child/app.js +11 -2
  13. package/jobs/child/forkProcess.js +81 -6
  14. package/jobs/child/index.js +41 -45
  15. package/jobs/child-pool/index.js +205 -0
  16. package/jobs/index.js +3 -1
  17. package/jobs/load-balancer/algorithm/index.js +12 -0
  18. package/jobs/load-balancer/algorithm/minimumConnection.js +19 -0
  19. package/jobs/load-balancer/algorithm/polling.js +12 -0
  20. package/jobs/load-balancer/algorithm/random.js +10 -0
  21. package/jobs/load-balancer/algorithm/specify.js +15 -0
  22. package/jobs/load-balancer/algorithm/weights.js +22 -0
  23. package/jobs/load-balancer/algorithm/weightsMinimumConnection.js +30 -0
  24. package/jobs/load-balancer/algorithm/weightsPolling.js +23 -0
  25. package/jobs/load-balancer/algorithm/weightsRandom.js +17 -0
  26. package/jobs/load-balancer/consts.js +10 -0
  27. package/jobs/load-balancer/index.js +202 -0
  28. package/jobs/load-balancer/scheduler.js +32 -0
  29. package/loader/index.js +22 -2
  30. package/message/childMessage.js +23 -0
  31. package/package.json +1 -6
  32. package/ps/index.js +44 -0
  33. package/tools/encrypt.js +105 -45
  34. package/utils/co.js +237 -0
  35. package/utils/depd/index.js +538 -0
  36. package/utils/depd/lib/browser/index.js +77 -0
  37. package/utils/extend.js +73 -0
  38. package/utils/get-port/index.d.ts +64 -0
  39. package/utils/get-port/index.js +109 -0
  40. package/utils/helper.js +25 -1
  41. package/utils/index.js +46 -0
  42. package/utils/ip.js +261 -0
  43. package/utils/is.js +2 -1
  44. package/utils/time/index.js +20 -0
  45. package/utils/time/ms.js +162 -0
  46. package/jobs/childPool/app.js +0 -62
  47. package/jobs/childPool/forkProcess.js +0 -81
  48. package/jobs/childPool/index.js +0 -71
  49. package/jobs/childPool/pool.js +0 -67
  50. /package/{oldUtils → old-utils}/index.js +0 -0
package/bin/tools.js CHANGED
@@ -16,3 +16,7 @@ if (cmd == 'rd') {
16
16
  if (cmd == 'encrypt') {
17
17
  encrypt.run();
18
18
  }
19
+
20
+ if (cmd == 'clean') {
21
+ encrypt.clean();
22
+ }
@@ -282,5 +282,14 @@ module.exports = appInfo => {
282
282
  }
283
283
  };
284
284
 
285
+ /**
286
+ * 异常捕获
287
+ */
288
+ config.exception = {
289
+ mainExit: false,
290
+ childExit: true,
291
+ rendererExit: true,
292
+ };
293
+
285
294
  return config;
286
295
  };
package/const/channel.js CHANGED
@@ -5,5 +5,14 @@ module.exports = {
5
5
  },
6
6
  socketIo: {
7
7
  partySoftware: 'c1',
8
- },
8
+ },
9
+ events: {
10
+ childProcessExit: 'ee#childProcess#exit',
11
+ childProcessError: 'ee#childProcess#error',
12
+ },
13
+ receiver: {
14
+ childJob: 'job',
15
+ forkProcess: 'task',
16
+ all: 'all'
17
+ }
9
18
  };
package/core/lib/ee.js CHANGED
@@ -2,7 +2,7 @@ const assert = require('assert');
2
2
  const fs = require('fs');
3
3
  const KoaApplication = require('koa');
4
4
  const is = require('is-type-of');
5
- const co = require('co');
5
+ const co = require('../../utils/co');
6
6
  const BaseContextClass = require('./utils/base_context_class');
7
7
  const utils = require('./utils');
8
8
  const Timing = require('./utils/timing');
@@ -6,11 +6,11 @@ const debug = require('debug')('ee-core:fileLoader');
6
6
  const path = require('path');
7
7
  const globby = require('globby');
8
8
  const is = require('is-type-of');
9
- const deprecate = require('depd')('ee');
9
+ const deprecate = require('../../../utils/depd')('ee');
10
10
  const Utils = require('../utils');
11
11
  const FULLPATH = Symbol('EE_LOADER_ITEM_FULLPATH');
12
12
  const EXPORTS = Symbol('EE_LOADER_ITEM_EXPORTS');
13
- const Addon = require('../../../addon');
13
+ //const Addon = require('../../../addon');
14
14
 
15
15
  const defaults = {
16
16
  directory: null,
@@ -2,7 +2,7 @@
2
2
 
3
3
  const debug = require('debug')('ee-core:config');
4
4
  const path = require('path');
5
- const extend = require('extend2');
5
+ const extend = require('../../../../utils/extend');
6
6
  const assert = require('assert');
7
7
  const { Console } = require('console');
8
8
 
@@ -5,7 +5,7 @@ const convert = require('koa-convert');
5
5
  const is = require('is-type-of');
6
6
  const path = require('path');
7
7
  const fs = require('fs');
8
- const co = require('co');
8
+ const co = require('../../../utils/co');
9
9
  const BuiltinModule = require('module');
10
10
 
11
11
  // Guard against poorly mocked module constructors.
package/ee/eeApp.js CHANGED
@@ -1,7 +1,6 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs');
3
3
  const assert = require('assert');
4
- const getPort = require('get-port');
5
4
  const { app } = require('electron');
6
5
  const is = require('is-type-of');
7
6
  const Koa = require('koa');
@@ -12,7 +11,8 @@ const Log = require('../log');
12
11
  const Electron = require('../electron');
13
12
  const Conf = require('../config');
14
13
  const Ps = require('../ps');
15
- const Socket = require('../socket')
14
+ const Socket = require('../socket');
15
+ const GetPort = require('../utils/get-port');
16
16
 
17
17
  class EeApp extends BaseApp {
18
18
  constructor(options = {}) {
@@ -26,18 +26,18 @@ class EeApp extends BaseApp {
26
26
  * 生成端口
27
27
  */
28
28
  async createPorts () {
29
- const mainPort = await getPort({port: this.config.mainServer.port});
29
+ const mainPort = await GetPort({port: this.config.mainServer.port});
30
30
  process.env.EE_MAIN_PORT = mainPort;
31
31
  this.config.mainServer.port = mainPort;
32
32
 
33
33
  if (this.config.socketServer.enable) {
34
- const socketPort = await getPort({port: this.config.socketServer.port});
34
+ const socketPort = await GetPort({port: this.config.socketServer.port});
35
35
  process.env.EE_SOCKET_PORT = socketPort;
36
36
  this.config.socketServer.port = socketPort;
37
37
  }
38
38
 
39
39
  if (this.config.httpServer.enable) {
40
- const httpPort = await getPort({port: this.config.httpServer.port});
40
+ const httpPort = await GetPort({port: this.config.httpServer.port});
41
41
  process.env.EE_HTTP_PORT = httpPort;
42
42
  this.config.httpServer.port = httpPort;
43
43
  }
@@ -119,7 +119,8 @@ class EeApp extends BaseApp {
119
119
  if (this.mainWindow.isMinimized()) {
120
120
  this.mainWindow.restore();
121
121
  }
122
- this.mainWindow.show()
122
+ this.mainWindow.show();
123
+ this.mainWindow.focus();
123
124
  }
124
125
  }
125
126
 
@@ -267,7 +268,7 @@ class EeApp extends BaseApp {
267
268
  }
268
269
 
269
270
  /**
270
- * 捕获异常
271
+ * 捕获异常(废弃)
271
272
  */
272
273
  async catchLog () {
273
274
  process.on('uncaughtException', function(err) {
@@ -1,6 +1,7 @@
1
1
  const Log = require('../log');
2
2
  const Ps = require('../ps');
3
- const Channel = require('../const/channel');
3
+ const Conf = require('../config');
4
+ const Message = require('../message');
4
5
 
5
6
  /**
6
7
  * 捕获异常
@@ -25,7 +26,9 @@ exports.uncaughtExceptionHandler = function() {
25
26
 
26
27
  Log.coreLogger.error(err);
27
28
 
28
- devError(err);
29
+ _devError(err);
30
+
31
+ _exit();
29
32
  });
30
33
  }
31
34
 
@@ -64,22 +67,47 @@ exports.unhandledRejectionHandler = function() {
64
67
 
65
68
  Log.coreLogger.error(err);
66
69
 
67
- devError(err);
70
+ _devError(err);
71
+
72
+ _exit();
68
73
  });
69
74
  }
70
75
 
71
76
  /**
72
77
  * 如果是子进程,发送错误到主进程控制台
73
78
  */
74
- function devError (err) {
79
+ function _devError (err) {
75
80
  if (Ps.isForkedChild() && Ps.isDev()) {
76
- let msgChannel = Channel.process.showException;
77
- let errTips = (err && typeof err == 'object') ? err.toString() : '';
78
- errTips += ' Error !!! Please See file ee-core.log or ee-error-xxx.log for details !'
79
- let message = {
80
- channel: msgChannel,
81
- data: errTips
82
- }
83
- process.send(message);
81
+ Message.childMessage.sendErrorToTerminal(err);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * 捕获异常后是否退出
87
+ */
88
+ function _exit () {
89
+ let cfg = Conf.getValue('exception');
90
+ if (!cfg) {
91
+ return;
92
+ }
93
+
94
+ if (Ps.isMain() && cfg.mainExit == true) {
95
+ _delayExit();
96
+ } else if (Ps.isForkedChild() && cfg.childExit == true) {
97
+ _delayExit();
98
+ } else if (Ps.isRenderer() && cfg.rendererExit == true) {
99
+ _delayExit();
100
+ } else {
101
+ // other
84
102
  }
103
+ }
104
+
105
+ /**
106
+ * 捕获异常后是否退出
107
+ */
108
+ function _delayExit() {
109
+ // 等待日志等异步写入完成
110
+ setTimeout(() => {
111
+ process.exit();
112
+ }, 1500)
85
113
  }
@@ -1,10 +1,10 @@
1
1
  const Agent = require('agentkeepalive');
2
2
  const HttpsAgent = require('agentkeepalive').HttpsAgent;
3
3
  const urllib = require('urllib');
4
- const ms = require('humanize-ms');
5
4
  const { FrameworkBaseError } = require('egg-errors');
6
5
  const Conf = require('../config');
7
6
  const Log = require('../log');
7
+ const Time = require('../utils/time');
8
8
 
9
9
  class HttpClientError extends FrameworkBaseError {
10
10
  get module() {
@@ -50,14 +50,6 @@ class HttpClient extends urllib.HttpClient2 {
50
50
  this.config = config;
51
51
  }
52
52
 
53
- /**
54
- * 获取 coredb
55
- */
56
- _getCoreDB() {
57
- const coreDB = Storage.connection('system');
58
- return coreDB;
59
- }
60
-
61
53
  request(url, args, callback) {
62
54
  if (typeof args === 'function') {
63
55
  callback = args;
@@ -116,7 +108,7 @@ function normalizeConfig(httpConfig) {
116
108
  config.httpsAgent.keepAlive = config.keepAlive;
117
109
  }
118
110
  if (config.timeout) {
119
- config.timeout = ms(config.timeout);
111
+ config.timeout = Time.ms(config.timeout);
120
112
  config.httpAgent.timeout = config.timeout;
121
113
  config.httpsAgent.timeout = config.timeout;
122
114
  }
@@ -126,7 +118,7 @@ function normalizeConfig(httpConfig) {
126
118
  delete config.freeSocketKeepAliveTimeout;
127
119
  }
128
120
  if (config.freeSocketTimeout) {
129
- config.freeSocketTimeout = ms(config.freeSocketTimeout);
121
+ config.freeSocketTimeout = Time.ms(config.freeSocketTimeout);
130
122
  config.httpAgent.freeSocketTimeout = config.freeSocketTimeout;
131
123
  config.httpsAgent.freeSocketTimeout = config.freeSocketTimeout;
132
124
  } else {
@@ -162,7 +154,7 @@ function normalizeConfig(httpConfig) {
162
154
  }
163
155
 
164
156
  if (typeof config.request.timeout === 'string') {
165
- config.request.timeout = ms(config.request.timeout);
157
+ config.request.timeout = Time.ms(config.request.timeout);
166
158
  }
167
159
  }
168
160
 
package/index.js CHANGED
@@ -30,7 +30,7 @@ const Storage = require('./storage');
30
30
  * @member {Utils}
31
31
  * @since 1.0.0
32
32
  */
33
- const Utils = require('./oldUtils');
33
+ const Utils = require('./old-utils');
34
34
 
35
35
  /**
36
36
  * @member {Socket}
package/jobs/child/app.js CHANGED
@@ -13,6 +13,7 @@ const UtilsCore = require('ee-core/core/lib/utils');
13
13
  // const UtilsCore = require('../../core/lib/utils');
14
14
 
15
15
  Exception.start();
16
+ const commands = ['run'];
16
17
 
17
18
  class ChildApp {
18
19
  constructor() {
@@ -24,7 +25,7 @@ class ChildApp {
24
25
  */
25
26
  _initEvents() {
26
27
  process.on('message', this._handleMessage.bind(this));
27
- process.on('exit', (code) => {
28
+ process.once('exit', (code) => {
28
29
  Log.coreLogger.info(`[ee-core] [jobs/child] received a exit from main-process, code:${code}, pid:${process.pid}`);
29
30
  });
30
31
  }
@@ -33,7 +34,15 @@ class ChildApp {
33
34
  * 监听消息
34
35
  */
35
36
  _handleMessage(m) {
36
- this.run(m);
37
+ if (commands.indexOf(m.cmd) == -1) {
38
+ return
39
+ }
40
+ switch (m.cmd) {
41
+ case 'run':
42
+ this.run(m);
43
+ break;
44
+ default:
45
+ }
37
46
  Log.coreLogger.info(`[ee-core] [jobs/child] received a message from main-process, message: ${JSON.stringify(m)}`);
38
47
  }
39
48
 
@@ -1,9 +1,11 @@
1
1
  const path = require('path');
2
+ const EventEmitter = require('events');
2
3
  const { fork } = require('child_process');
3
4
  const serialize = require('serialize-javascript');
4
5
  const Log = require('../../log');
5
6
  const Ps = require('../../ps');
6
7
  const Channel = require('../../const/channel');
8
+ const Helper = require('../../utils/helper');
7
9
 
8
10
  class ForkProcess {
9
11
  constructor(host, opt = {}) {
@@ -16,6 +18,7 @@ class ForkProcess {
16
18
  }
17
19
 
18
20
  let options = Object.assign({
21
+ processArgs: {},
19
22
  processOptions: {
20
23
  cwd: cwd,
21
24
  env: Ps.allEnv(),
@@ -23,12 +26,13 @@ class ForkProcess {
23
26
  }
24
27
  }, opt);
25
28
 
29
+ this.emitter = new EventEmitter();
26
30
  this.host = host;
27
31
  this.args = [];
28
32
  this.sleeping = false;
29
33
 
30
34
  // 传递给子进程的参数
31
- //this.args.push(JSON.stringify(options.params));
35
+ this.args.push(JSON.stringify(options.processArgs));
32
36
 
33
37
  this.child = fork(appPath, this.args, options.processOptions);
34
38
  this.pid = this.child.pid;
@@ -36,7 +40,7 @@ class ForkProcess {
36
40
  }
37
41
 
38
42
  /**
39
- * 进程初始化
43
+ * 初始化事件监听
40
44
  */
41
45
  _init() {
42
46
  this.child.on('message', (m) => {
@@ -47,20 +51,91 @@ class ForkProcess {
47
51
 
48
52
  // 收到子进程消息,转发到 event
49
53
  if (m.channel == Channel.process.sendToMain) {
50
- this.host.emit(m.event, m.data);
54
+ this._eventEmit(m);
51
55
  }
52
-
53
56
  });
54
57
 
55
58
  this.child.on('exit', (code, signal) => {
56
- Log.coreLogger.info(`[ee-core] [jobs/child] received a exit from child-process, code:${code}, signal:${signal}`);
59
+ let data = {
60
+ pid: this.pid
61
+ }
62
+ this.host.emit(Channel.events.childProcessExit, data);
63
+ Log.coreLogger.info(`[ee-core] [jobs/child] received a exit from child-process, code:${code}, signal:${signal}, pid:${this.pid}`);
57
64
  });
58
65
 
59
66
  this.child.on('error', (err) => {
60
- Log.coreLogger.error(`[ee-core] [jobs/child] received a error from child-process, error: ${err} !`);
67
+ let data = {
68
+ pid: this.pid
69
+ }
70
+ this.host.emit(Channel.events.childProcessError, data);
71
+ Log.coreLogger.error(`[ee-core] [jobs/child] received a error from child-process, error: ${err}, pid:${this.pid}`);
61
72
  });
62
73
  }
63
74
 
75
+ /**
76
+ * event emit
77
+ */
78
+ _eventEmit(m) {
79
+ switch (m.eventReceiver) {
80
+ case Channel.receiver.forkProcess:
81
+ this.emitter.emit(m.event, m.data);
82
+ break;
83
+ case Channel.receiver.childJob:
84
+ this.host.emit(m.event, m.data);
85
+ break;
86
+ default:
87
+ this.host.emit(m.event, m.data);
88
+ this.emitter.emit(m.event, m.data);
89
+ break;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * 分发任务
95
+ */
96
+ dispatch(cmd, jobPath = '', params = {}) {
97
+ // 消息对象
98
+ const mid = Helper.getRandomString();
99
+ let msg = {
100
+ mid,
101
+ cmd,
102
+ jobPath,
103
+ jobParams: params
104
+ }
105
+
106
+ // todo 是否会发生监听未完成时,接收不到消息?
107
+ // 发消息到子进程
108
+ this.child.send(msg);
109
+ }
110
+
111
+ /**
112
+ * kill
113
+ */
114
+ kill(timeout = 1000) {
115
+ this.child.kill('SIGINT');
116
+ setTimeout(() => {
117
+ if (this.child.killed) return;
118
+ this.child.kill('SIGKILL');
119
+ }, timeout)
120
+ }
121
+
122
+ /**
123
+ * sleep (仅Unix平台)
124
+ */
125
+ sleep() {
126
+ if (this.sleeping) return;
127
+ process.kill(this.pid, 'SIGSTOP');
128
+ this.sleeping = true;
129
+ }
130
+
131
+ /**
132
+ * wakeup (仅Unix平台)
133
+ */
134
+ wakeup() {
135
+ if (!this.sleeping) return;
136
+ process.kill(this.pid, 'SIGCONT');
137
+ this.sleeping = false;
138
+ }
64
139
  }
65
140
 
66
141
  module.exports = ForkProcess;
@@ -1,76 +1,72 @@
1
1
  const EventEmitter = require('events');
2
- const path = require('path');
3
- const fs = require('fs');
4
2
  const ForkProcess = require('./forkProcess');
5
- const Ps = require('../../ps');
6
3
  const Loader = require('../../loader');
7
- const Helper = require('../../utils/helper');
4
+ const Channel = require('../../const/channel');
8
5
 
9
6
  class ChildJob extends EventEmitter {
10
7
 
11
8
  constructor() {
12
9
  super();
13
- this.initEvents();
10
+ this.jobs = {};
11
+ this._initEvents();
14
12
  }
15
13
 
16
14
  /**
17
15
  * 初始化监听
18
16
  */
19
- initEvents = () => {
20
-
21
- // this.on('forked_message', ({data, id}) => {
22
- // this.onMessage({data, id});
23
- // });
17
+ _initEvents() {
18
+ this.on(Channel.events.childProcessExit, (data) => {
19
+ delete this.jobs[data.pid];
20
+ });
21
+ this.on(Channel.events.childProcessError, (data) => {
22
+ delete this.jobs[data.pid];
23
+ });
24
24
  }
25
25
 
26
26
  /**
27
27
  * 执行一个job文件
28
28
  */
29
29
  exec(filepath, params = {}, opt = {}) {
30
- const jobPath = this._getFullpath(filepath);
31
-
32
- // 消息对象
33
- const mid = Helper.getRandomString();
34
- let msg = {
35
- mid,
36
- jobPath,
37
- jobParams: params
38
- }
39
-
40
- let subProcess = new ForkProcess(this, opt);
41
-
42
- // todo 是否会发生监听未完成时,接收不到消息?
43
- // 发消息到子进程
44
- subProcess.child.send(msg);
30
+ const jobPath = Loader.getFullpath(filepath);
31
+ const proc = this.createProcess(opt);
32
+ const cmd = 'run';
33
+ proc.dispatch(cmd, jobPath, params);
45
34
 
46
- return subProcess;
35
+ return proc;
47
36
  }
48
37
 
49
38
  /**
50
- * todo 运行job
39
+ * 创建子进程
51
40
  */
52
- run(name, filepath, opt = {}) {
53
- let times = opt.times || 1;
54
-
55
- for (let i = 1; i <= times; i++) {
56
- this.exec(filepath, opt);
41
+ createProcess(opt = {}) {
42
+ let options = Object.assign({
43
+ processArgs: {
44
+ type: 'childJob'
45
+ }
46
+ }, opt);
47
+ const proc = new ForkProcess(this, options);
48
+ if (!proc) {
49
+ let errorMessage = `[ee-core] [jobs/child] Failed to obtain the child process !`
50
+ throw new Error(errorMessage);
57
51
  }
58
-
59
- return;
60
- }
52
+ this.jobs[proc.pid] = proc;
61
53
 
62
- _getFullpath(filepath) {
63
- const isAbsolute = path.isAbsolute(filepath);
64
- if (!isAbsolute) {
65
- filepath = path.join(Ps.getBaseDir(), filepath);
66
- }
54
+ return proc;
55
+ }
67
56
 
68
- const fullpath = Loader.resolveModule(filepath);
69
- if (!fs.existsSync(fullpath)) {
70
- throw new Error(`[ee-core] [jobs/child] file ${fullpath} not exists`);
71
- }
57
+ /**
58
+ * 获取当前pids
59
+ */
60
+ getPids() {
61
+ let pids = Object.keys(this.jobs);
62
+ return pids;
63
+ }
72
64
 
73
- return fullpath;
65
+ /**
66
+ * 异步执行一个job文件 todo this指向
67
+ */
68
+ async execPromise(filepath, params = {}, opt = {}) {
69
+ return this.exec(filepath, params, opt);
74
70
  }
75
71
 
76
72
  }