agent.js 2.4 KB

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