333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'use strict';
 
const path = require('path');
const ms = require('ms');
const EggApplication = require('./egg');
const AgentWorkerLoader = require('./loader').AgentWorkerLoader;
 
const EGG_LOADER = Symbol.for('egg#loader');
const EGG_PATH = Symbol.for('egg#eggPath');
 
/**
 * Singleton instance in Agent Worker, extend {@link EggApplication}
 * @extends EggApplication
 */
class Agent extends EggApplication {
  /**
   * @class
   * @param {Object} options - see {@link EggApplication}
   */
  constructor(options = {}) {
    options.type = 'agent';
    super(options);
 
    this.loader.load();
 
    // dump config after loaded, ensure all the dynamic modifications will be recorded
    const dumpStartTime = Date.now();
    this.dumpConfig();
    this.coreLogger.info('[egg:core] dump config after load, %s', ms(Date.now() - dumpStartTime));
 
    // keep agent alive even it doesn't have any io tasks
    setInterval(() => {}, 24 * 60 * 60 * 1000);
 
    this._uncaughtExceptionHandler = this._uncaughtExceptionHandler.bind(this);
    process.on('uncaughtException', this._uncaughtExceptionHandler);
  }
 
  _uncaughtExceptionHandler(err) {
    if (!(err instanceof Error)) {
      err = new Error(String(err));
    }
    /* istanbul ignore else */
    if (err.name === 'Error') {
      err.name = 'unhandledExceptionError';
    }
    this.coreLogger.error(err);
  }
 
  get [EGG_LOADER]() {
    return AgentWorkerLoader;
  }
 
  get [EGG_PATH]() {
    return path.join(__dirname, '..');
  }
 
  _wrapMessenger() {
    for (const methodName of [ 'broadcast', 'sendTo', 'sendToApp', 'sendToAgent', 'sendRandom' ]) {
      wrapMethod(methodName, this.messenger, this.coreLogger);
    }
 
    function wrapMethod(methodName, messenger, logger) {
      const originMethod = messenger[methodName];
      messenger[methodName] = function() {
        const stack = new Error().stack.split('\n').slice(1).join('\n');
        logger.warn('agent can\'t call %s before server started\n%s',
          methodName, stack);
        originMethod.apply(this, arguments);
      };
      messenger.prependOnceListener('egg-ready', () => {
        messenger[methodName] = originMethod;
      });
    }
  }
 
  close() {
    process.removeListener('uncaughtException', this._uncaughtExceptionHandler);
    return super.close();
  }
 
}
 
module.exports = Agent;