All Projects → hexindai → egg-bus

hexindai / egg-bus

Licence: MIT license
🐣 用 egg 编写优雅的队列与事件

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to egg-bus

Nideadmin
【未完成】NideAdmin - 基于 Vue.js + Egg.js 的微信小程序后台框架
Stars: ✭ 35 (-7.89%)
Mutual labels:  egg, eggjs
Egg Router Plus
The missing router feature for eggjs
Stars: ✭ 117 (+207.89%)
Mutual labels:  egg, eggjs
Egg Cancan
cancancan like authorization plugin for Egg.js
Stars: ✭ 47 (+23.68%)
Mutual labels:  egg, eggjs
Egg Graphql
Stars: ✭ 345 (+807.89%)
Mutual labels:  egg, eggjs
egg-view-assets
Manage frontend assets in development and production.
Stars: ✭ 51 (+34.21%)
Mutual labels:  egg, eggjs
Egg 24time
A Twitter-like news and social server for Egg. 微信小程序社区全栈解决方案
Stars: ✭ 493 (+1197.37%)
Mutual labels:  egg, eggjs
Blog
天猪部落阁 http://atian25.github.io
Stars: ✭ 1,527 (+3918.42%)
Mutual labels:  egg, eggjs
egg-nuxt-blog
Nuxt.js(web端) + Egg.js(api 服务) + Vue.js(管理后台)+ ElementUI(通用组件库)服务器渲染(SSR)搭建的个人博客系统
Stars: ✭ 16 (-57.89%)
Mutual labels:  egg, eggjs
nest-queue
Queue manager for NestJS Framework for Redis (via bull package)
Stars: ✭ 69 (+81.58%)
Mutual labels:  queue, bull
Cool Admin Api
cool-admin-api 是基于egg.js、typeorm、jwt等封装的api开发脚手架、快速开发api接口
Stars: ✭ 188 (+394.74%)
Mutual labels:  egg, eggjs
Egg
🥚 Born to build better enterprise frameworks and apps with Node.js & Koa
Stars: ✭ 17,616 (+46257.89%)
Mutual labels:  egg, eggjs
egg-rbac
Role Based Access Control for eggjs
Stars: ✭ 32 (-15.79%)
Mutual labels:  egg, eggjs
docker
Egg official docker image
Stars: ✭ 26 (-31.58%)
Mutual labels:  egg, eggjs
Eggjs Note
《Egg.js 深入浅出学习笔记》(暂时停更)
Stars: ✭ 502 (+1221.05%)
Mutual labels:  egg, eggjs
egg-vue-typescript-boilerplate
Egg Vue TypeScript Server Side Render (SSR) / Client Side Render (CSR)
Stars: ✭ 69 (+81.58%)
Mutual labels:  egg, eggjs
Egg Authz
egg-authz is an authorization middleware for Egg.js based on Casbin
Stars: ✭ 50 (+31.58%)
Mutual labels:  egg, eggjs
egg-parameters
Merge all parameters (ctx.params, ctx.request.query, ctx.request.body) into ctx.params like Rails application.
Stars: ✭ 24 (-36.84%)
Mutual labels:  egg, eggjs
Egg Oauth2 Server
🌟 OAuth2 server plugin for egg.js based on node-oauth2-server
Stars: ✭ 174 (+357.89%)
Mutual labels:  egg, eggjs
sf-midway-admin
🚀 基于MidwayJs + TypeScript + TypeORM + Redis + MySql + Vue2 + Element-UI编写的一款简单高效的前后端分离的权限管理系统
Stars: ✭ 93 (+144.74%)
Mutual labels:  bull, eggjs
egg-sentry
Sentry Plugin For Egg.js
Stars: ✭ 18 (-52.63%)
Mutual labels:  egg, eggjs

egg-bus

NPM version build status Test coverage David deps Known Vulnerabilities npm download

🐣 用 egg 编写优雅的队列与事件,基于 bull 实现

安装

$ npm i egg-bus bull --save

使用

exports.bus = {
  enable: true,
  package: "egg-bus",
};

配置

// {app_root}/config/config.default.js
exports.bus = {
  debug: true, // Debug 模式下会打印更多日志信息
  concurrency: 1, // Bull 中队列处理的并发数:https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queueprocess
  listener: {
    ignore: null, // 忽略目录中的某些文件,https://eggjs.org/zh-cn/advanced/loader.html#ignore-string
    baseDir: "listener",
    options: {
      // Bull Job 配置: https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queueadd
      attempts: 5,
      backoff: {
        delay: 3000,
        type: "fixed",
      },
    },
  },
  job: {
    // 与 listener 一致,唯一不同的就是 默认 baseDir 的值为 `job`
  },
  bull: {
    // Bull 队列配置:https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queue
    redis: {
      host: "localhost",
      port: 6379,
      db: 0,
    },
  },

  queue: {
    default: "default", // 默认队列名称
    prefix: "bus", // 队列前缀
  },
  queues: {
    // 针对不同队列单独配置

    // 比如针对默认队列更改 redis 端口
    default: {
      concurrency: 2, // 针对队列单独设置并发
      redis: {
        port: 6380,
      },
    },
  },
};

更多配置说明请查看 config/config.default.js

使用

bus 会读取 app 目录中的 listenerjob 目录(默认,可通过配置修改)并解析 相关配置。

app
├── controller
│   ├── home.ts
├── job        <-- 队列目录
│   └── something.ts
├── listener   <-- 事件监听目录
│   ├── spy.ts
├── router.ts

Job

job 是队列中的一项任务。在 app/job 目录,定义一个 job

const { Job } = require("egg-bus");

class DemoJob extends Job {
  static get queue() {
    return "queue_name"; // 使用的队列名称
  }

  static get attempts() {
    return 5; // 重试次数
  }

  async run(data, job) {
    // job 任务运行时调用
    // 第一个参数是发送过来的数据
    // 第二个参数是 Bull 的原始 Job 对象
    // 通过 this.ctx 和 this.app 分别获取 egg 的 Context 和 Application 对象
  }

  failed(data) {
    // 当 job 失败并重试达到限定次数后调用
  }
}

module.exports = DemoJob;

在 run 中抛出任何未捕获的异常都会认为 job 执行失败,会在指定次数内重新尝试。

通过 dispatch 方法触发一个 job

const data = { name: "abel" };
app.bus.dispatch("demo", data);

Listener

listener 用于监听事件发生并执行某些任务。很多情况下,我们需要将核心业务与一些耗时 任务分开来提高响应速度或解耦增强可维护性和移植性。

nodejs 本身支持异步,可以解决响应速度的问题,基于事件,也可以达到解耦的目的。但实 际使用起来却有很多麻烦:

  1. 在异步中运行的代码如果不使用 app.runInBackground 就无法被 egg 捕获异常而记录日志;
  2. 如果发生错误,没有重试机制;
  3. nodejs 本身的 event 机制在 listener 数量上有限制,虽然可以通过参数提高这个阈值, 但这可能引发其它问题。
  4. 不够优雅!不够优雅!不够优雅!有很多类似的模块来解决这些问题,但大多只提供了基础功能。 比如告诉你怎么创建队列,怎么监听队列,却并没有告诉你这些创建队列、监听队列的代码应该放在何处。

因此,为了解决上面这些问题,参考 laravel 的事件机制设计了 listener

const { Listener } = require("egg-bus");

class DemoListener extends Listener {
  static get watch() {
    return ["opened", "visited"]; // 监听的事件名称
  }

  static get queue() {
    return "queue_name"; // 使用的队列名称
  }

  static get attempts() {
    return 5; // 重试次数
  }

  async run(event, job) {
    // listener 任务运行时调用
    // 与 job 不同,第一个参数是 event 对象,其中包含以下值:
    // - name 事件名称
    // - data 数据
    // 第二个参数是 Bull 的原始 Job 对象
    // 通过 this.ctx 和 this.app 分别获取 egg 的 Context 和 Application 对象
    console.log(event.name, event.data);
  }

  failed(event, error, job) {
    // 当 listener 失败并重试达到限定次数后调用
  }
}

module.exports = DemoListener;

事件的监听并不需要编写对应关系,你只需要告诉 listener 需要注意哪些事件就行了。

通过 emit 方法触发一个 事件

const data = { name: "abel" };
app.bus.emit("opened", data);

Api 参考

所有可用的 api 都位于 app.bus 对象下:

dispatch

触发一个任务

dispatch(name: string, payload?: any, options?: JobOptions): void
  • name 任务名,和 job 文件名一致
  • payload 发送的数据
  • options Bull Job 的一些定制化选项

emit

触发一个事件

emit(name: string, payload?: any, options?: JobOptions): void
  • name 事件名称
  • payload 发送的数据
  • options Bull Job 的一些定制化选项

get

获取原始的 Bull 队列实例

get(name: string): Queue
  • name 队列名称

问题和建议

请创建 issue.

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].