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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'use strict';
 
const loadSchedule = require('./lib/load_schedule');
const qs = require('querystring');
const path = require('path');
 
module.exports = app => {
  const logger = app.getLogger('scheduleLogger');
  const schedules = loadSchedule(app);
 
  // log schedule list
  for (const s in schedules) {
    const schedule = schedules[s];
    if (!schedule.schedule.disable) logger.info('[egg-schedule]: register schedule %s', schedule.key);
  }
 
  // register schedule event
  app.messenger.on('egg-schedule', info => {
    const { id, key } = info;
    const schedule = schedules[key];
 
    logger.debug(`[Job#${id}] ${key} task received by app`);
 
    if (!schedule) {
      logger.warn(`[Job#${id}] ${key} unknown task`);
      return;
    }
 
    /* istanbul ignore next */
    if (schedule.schedule.disable) {
      logger.warn(`[Job#${id}] ${key} disable`);
      return;
    }
 
    logger.info(`[Job#${id}] ${key} executing by app`);
 
    // run with anonymous context
    const ctx = app.createAnonymousContext({
      method: 'SCHEDULE',
      url: `/__schedule?path=${key}&${qs.stringify(schedule.schedule)}`,
    });
 
    const start = Date.now();
 
    // execute
    return schedule.task(ctx, ...info.args)
      .catch(err => {
        logger.error(`[Job#${id}] ${key} execute error.`, err);
        return err;
      })
      .then(err => {
        const success = !err;
        const rt = Date.now() - start;
 
        logger[success ? 'info' : 'error'](`[Job#${id}] ${key} execute ${success ? 'succeed' : 'failed'}, used ${rt}ms`);
 
        Object.assign(info, {
          success,
          workerId: process.pid,
          rt,
          message: err && err.message,
        });
 
        // notify agent job finish
        app.messenger.sendToAgent('egg-schedule', info);
      });
  });
 
  // for test purpose
  const directory = [].concat(path.join(app.config.baseDir, 'app/schedule'), app.config.schedule.directory || []);
  app.runSchedule = (schedulePath, ...args) => {
    // resolve real path
    if (path.isAbsolute(schedulePath)) {
      schedulePath = require.resolve(schedulePath);
    } else {
      for (const dir of directory) {
        try {
          schedulePath = require.resolve(path.join(dir, schedulePath));
          break;
        } catch (_) {
          /* istanbul ignore next */
        }
      }
    }
 
    let schedule;
 
    try {
      schedule = schedules[schedulePath];
      if (!schedule) {
        throw new Error(`Cannot find schedule ${schedulePath}`);
      }
    } catch (err) {
      err.message = `[egg-schedule] ${err.message}`;
      return Promise.reject(err);
    }
 
    // run with anonymous context
    const ctx = app.createAnonymousContext({
      method: 'SCHEDULE',
      url: `/__schedule?path=${schedulePath}&${qs.stringify(schedule.schedule)}`,
    });
 
    return schedule.task(ctx, ...args);
  };
};