index.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * Copyright(c) node-modules and other contributors.
  3. * MIT Licensed
  4. *
  5. * Authors:
  6. * fengmk2 <m@fengmk2.com> (http://fengmk2.com)
  7. */
  8. "use strict";
  9. /**
  10. * Module dependencies.
  11. */
  12. var cluster = require('cluster');
  13. module.exports = reload;
  14. // Windows not support SIGQUIT https://nodejs.org/api/process.html#process_signal_events
  15. var KILL_SIGNAL = 'SIGTERM';
  16. var reloading = false;
  17. var reloadPedding = false;
  18. function reload(count) {
  19. if (reloading) {
  20. reloadPedding = true;
  21. return;
  22. }
  23. if (!count) {
  24. count = require('os').cpus().length;
  25. }
  26. reloading = true;
  27. // find out all alive workers
  28. var aliveWorkers = [];
  29. var worker;
  30. for (var id in cluster.workers) {
  31. worker = cluster.workers[id];
  32. if (worker.state === 'disconnected') {
  33. continue;
  34. }
  35. aliveWorkers.push(worker);
  36. }
  37. var firstWorker;
  38. var newWorker;
  39. function reset() {
  40. // don't leak
  41. newWorker.removeListener('listening', reset);
  42. newWorker.removeListener('error', reset);
  43. if (firstWorker) {
  44. // console.log('firstWorker %s %s', firstWorker.id, firstWorker.state);
  45. firstWorker.kill(KILL_SIGNAL);
  46. setTimeout(function () {
  47. firstWorker.process.kill(KILL_SIGNAL);
  48. }, 100);
  49. }
  50. reloading = false;
  51. if (reloadPedding) {
  52. // has reload jobs, reload again
  53. reloadPedding = false;
  54. reload(count);
  55. }
  56. }
  57. firstWorker = aliveWorkers[0];
  58. newWorker = cluster.fork();
  59. newWorker.on('listening', reset).on('exit', reset);
  60. // kill other workers
  61. for (var i = 1; i < aliveWorkers.length; i++) {
  62. worker = aliveWorkers[i];
  63. // console.log('worker %s %s', worker.id, worker.state);
  64. worker.kill(KILL_SIGNAL);
  65. }
  66. // keep workers number as before
  67. var left = count - 1;
  68. for (var j = 0; j < left; j++) {
  69. cluster.fork();
  70. }
  71. }