egg-startup-runner
Run startup codes in parallel and serially from different files
依赖说明
依赖的 egg 版本
egg-startup-runner 版本 | egg 2.x |
---|---|
2.x | |
1.x | |
0.x | ❌ |
开启插件
// config/plugin.js
exports.startupRunner = {
enable: true,
package: 'egg-startup-runner',
};
使用场景
背景
部分初始化工作较为复杂,全部写在app
或agent
中相对拥挤,所以将这些初始化工作放在不同的文件中,由插件负责加载运行
使用方式
配置
插件默认从app/boot
目录中加载需要运行的文件,可以在配置改变读取的目录,例如下方的配置将读取app/startup1
和app/startup2
中的文件。
// config/config.default.js
exports.startupRunner = {
paths: [ 'startup1', 'startup2' ]
}
注意插件只会读取配置在paths中的目录,也就是说插件不会将子文件夹中的文件也读取加载,要读取子文件夹时需要将子文件夹路径也配置出来。例如
// config/config.default.js
exports.startupRunner = {
paths: [ 'startup1', 'startup1/subStartup1' ]
}
加载文件
需要加载的文件要特定的结构才能生效,结构类似egg
的定时任务schedule
// app/boot/init.js
module.exports = pro => {
return {
options: {
order: 8,
app: true,
agent: true,
didLoad: true,
willReady: true,
didReady: true,
serverDidReady: true
},
async start(meta) {
if (meta.pname === 'app') {
pro.str = 8;
}
if (meta.stage === 'willReady') {
pro.vit = 8;
}
},
};
};
如上方代码所示,是一个基本加载文件结构,options
中定义了运行顺序、需要运行的进程和生命周期。对应布尔值选项为false
时可以不写。
插件加载文件后将按照options
中的order
对所有文件进行升序排序,在同一个生命周期内,order
越小优先级最高,最先被执行。此外在同一个生命周期内,order
相同的将会并行执行,可用于相互没有关联的逻辑。order
默认值为0
。
options
中的app
和agent
选项表示代码将在哪个进程运行,在设置了app
为true
后插件将在app
对应的生命周期运行该文件的start
函数,pro
参数则是当前运行的进程app
实例。同理,在agent
设置为true
后agent
也会运行start
函数,pro
参数也自然是agent
实例。
options
中didLoad
、willReady
、didReady
和serverDidReady
对应需要运行的生命周期,设置为true
后将在相应的生命周期内运行start
函数。
start
函数被调用时插件会将当前的执行进程和生命周期作为参数传入,如上meta
中的pname
为当前的执行进程名字,值为"app"
或"agent"
。stage
为当前的生命周期名字,值"didLoad"
、"willReady"
、"didReady"
和"serverDidReady"
中的一个。
单次运行
一些初始任务只需要单个进程运行(也可以交由agent
进程运行,agent
毕竟只有一个,这里设置的是单个app
中的情况),此时可通过以下方式进行。注意,由于目前只能通过进程间通讯较为简单地达成向任意单个worker(app)
进程发送命令,所以单次运行的任务只会在serverDidReady
生命周期后运行。
// app/boot/once.js
module.exports = app => {
return {
options: {
order: 1,
app: true,
once: true
},
async start(meta) {
if (meta.pname === 'app') {
app.str = 8;
}
if (meta.stage === 'once') {
app.vit = 8;
}
},
};
};
app: true
必选。
由于设置了once
,once
的任务执行时只会在app
进行,所以传入的参数只会是app实例,当然,如果设置了agent
和其它生命周期,在对应周期也会是对应实例。
once
任务中,meta
参数将传入字符串"app"
和"once"
。