app.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. const loadSchedule = require('./lib/load_schedule');
  3. const qs = require('querystring');
  4. const path = require('path');
  5. const is = require('is-type-of');
  6. module.exports = app => {
  7. const logger = app.getLogger('scheduleLogger');
  8. const schedules = loadSchedule(app);
  9. // log schedule list
  10. for (const s in schedules) {
  11. const schedule = schedules[s];
  12. if (!schedule.schedule.disable) logger.info('[egg-schedule]: register schedule %s', schedule.key);
  13. }
  14. // register schedule event
  15. app.messenger.on('egg-schedule', info => {
  16. const { id, key } = info;
  17. const schedule = schedules[key];
  18. logger.debug(`[Job#${id}] ${key} task received by app`);
  19. if (!schedule) {
  20. logger.warn(`[Job#${id}] ${key} unknown task`);
  21. return;
  22. }
  23. /* istanbul ignore next */
  24. if (schedule.schedule.disable) {
  25. logger.warn(`[Job#${id}] ${key} disable`);
  26. return;
  27. }
  28. logger.info(`[Job#${id}] ${key} executing by app`);
  29. // run with anonymous context
  30. const ctx = app.createAnonymousContext({
  31. method: 'SCHEDULE',
  32. url: `/__schedule?path=${key}&${qs.stringify(schedule.schedule)}`,
  33. });
  34. const start = Date.now();
  35. // execute
  36. return schedule.task(ctx, ...info.args)
  37. .catch(err => {
  38. return is.error(err) ? err : new Error(err);
  39. })
  40. .then(err => {
  41. const success = !is.error(err);
  42. const rt = Date.now() - start;
  43. const msg = `[Job#${id}] ${key} execute ${success ? 'succeed' : 'failed'}, used ${rt}ms.`;
  44. logger[success ? 'info' : 'error'](msg, success ? '' : err);
  45. Object.assign(info, {
  46. success,
  47. workerId: process.pid,
  48. rt,
  49. message: err && err.message,
  50. });
  51. // notify agent job finish
  52. app.messenger.sendToAgent('egg-schedule', info);
  53. });
  54. });
  55. // for test purpose
  56. const directory = [].concat(path.join(app.config.baseDir, 'app/schedule'), app.config.schedule.directory || []);
  57. app.runSchedule = (schedulePath, ...args) => {
  58. // resolve real path
  59. if (path.isAbsolute(schedulePath)) {
  60. schedulePath = require.resolve(schedulePath);
  61. } else {
  62. for (const dir of directory) {
  63. try {
  64. schedulePath = require.resolve(path.join(dir, schedulePath));
  65. break;
  66. } catch (_) {
  67. /* istanbul ignore next */
  68. }
  69. }
  70. }
  71. let schedule;
  72. try {
  73. schedule = schedules[schedulePath];
  74. if (!schedule) {
  75. throw new Error(`Cannot find schedule ${schedulePath}`);
  76. }
  77. } catch (err) {
  78. err.message = `[egg-schedule] ${err.message}`;
  79. return Promise.reject(err);
  80. }
  81. // run with anonymous context
  82. const ctx = app.createAnonymousContext({
  83. method: 'SCHEDULE',
  84. url: `/__schedule?path=${schedulePath}&${qs.stringify(schedule.schedule)}`,
  85. });
  86. return schedule.task(ctx, ...args);
  87. };
  88. };