app_worker.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. 'use strict';
  2. // $ node app_worker.js options
  3. const options = JSON.parse(process.argv[2]);
  4. if (options.require) {
  5. // inject
  6. options.require.forEach(mod => {
  7. require(mod);
  8. });
  9. }
  10. const fs = require('fs');
  11. const debug = require('debug')('egg-cluster');
  12. const gracefulExit = require('graceful-process');
  13. const ConsoleLogger = require('egg-logger').EggConsoleLogger;
  14. const consoleLogger = new ConsoleLogger({
  15. level: process.env.EGG_APP_WORKER_LOGGER_LEVEL,
  16. });
  17. const Application = require(options.framework).Application;
  18. debug('new Application with options %j', options);
  19. let app;
  20. try {
  21. app = new Application(options);
  22. } catch (err) {
  23. consoleLogger.error(err);
  24. throw err;
  25. }
  26. const clusterConfig = app.config.cluster || /* istanbul ignore next */ {};
  27. const listenConfig = clusterConfig.listen || /* istanbul ignore next */ {};
  28. const httpsOptions = Object.assign({}, clusterConfig.https, options.https);
  29. const port = options.port = options.port || listenConfig.port;
  30. const protocol = (httpsOptions.key && httpsOptions.cert) ? 'https' : 'http';
  31. process.send({
  32. to: 'master',
  33. action: 'realport',
  34. data: {
  35. port,
  36. protocol,
  37. },
  38. });
  39. app.ready(startServer);
  40. function exitProcess() {
  41. // Use SIGTERM kill process, ensure trigger the gracefulExit
  42. process.exitCode = 1;
  43. process.kill(process.pid);
  44. }
  45. // exit if worker start timeout
  46. app.once('startTimeout', startTimeoutHandler);
  47. function startTimeoutHandler() {
  48. consoleLogger.error('[app_worker] start timeout, exiting with code:1');
  49. exitProcess();
  50. }
  51. function startServer(err) {
  52. if (err) {
  53. consoleLogger.error(err);
  54. consoleLogger.error('[app_worker] start error, exiting with code:1');
  55. exitProcess();
  56. return;
  57. }
  58. app.removeListener('startTimeout', startTimeoutHandler);
  59. let server;
  60. // https config
  61. if (httpsOptions.key && httpsOptions.cert) {
  62. httpsOptions.key = fs.readFileSync(httpsOptions.key);
  63. httpsOptions.cert = fs.readFileSync(httpsOptions.cert);
  64. httpsOptions.ca = httpsOptions.ca && fs.readFileSync(httpsOptions.ca);
  65. server = require('https').createServer(httpsOptions, app.callback());
  66. } else {
  67. server = require('http').createServer(app.callback());
  68. }
  69. server.once('error', err => {
  70. consoleLogger.error('[app_worker] server got error: %s, code: %s', err.message, err.code);
  71. exitProcess();
  72. });
  73. // emit `server` event in app
  74. app.emit('server', server);
  75. if (options.sticky) {
  76. server.listen(options.stickyWorkerPort, '127.0.0.1');
  77. // Listen to messages sent from the master. Ignore everything else.
  78. process.on('message', (message, connection) => {
  79. if (message !== 'sticky-session:connection') {
  80. return;
  81. }
  82. // Emulate a connection event on the server by emitting the
  83. // event with the connection the master sent us.
  84. server.emit('connection', connection);
  85. connection.resume();
  86. });
  87. } else {
  88. if (listenConfig.path) {
  89. server.listen(listenConfig.path);
  90. } else {
  91. if (typeof port !== 'number') {
  92. consoleLogger.error('[app_worker] port should be number, but got %s(%s)', port, typeof port);
  93. exitProcess();
  94. return;
  95. }
  96. const args = [ port ];
  97. if (listenConfig.hostname) args.push(listenConfig.hostname);
  98. debug('listen options %s', args);
  99. server.listen(...args);
  100. }
  101. }
  102. }
  103. gracefulExit({
  104. logger: consoleLogger,
  105. label: 'app_worker',
  106. beforeExit: () => app.close(),
  107. });