Nodejs定时任务库agenda5.0.0文档翻译

Agenda 的好处


  • 尽量减少开销,agenda 的目标是保持代码库的小型化。

  • Mongo 支持的持久层。

  • 基于 Promises 的 API。

  • 具有可配置优先级、并发性、重复性和作业结果持久性的调度。

  • 通过 cron 或人类可读语法进行调度。

  • 可以挂钩到的事件支持作业队列。

  • optional standalone web-interface: 可选的独立 REST API。

  • 反转议程-反转议程工作者发展的一些实用程序。

  • Agendash: 可选的独立 Web 界面。

    注意:

    翻译版本为Agenda 5.0.0,大部分为机器翻译,约定job翻译为作业。

Feature Comparison

由于存在一些作业队列解决方案,这里有一个表格对它们进行比较,以帮助您使用更适合您需要的解决方案。

如果您需要 MongoDB 作业调度程序,那么您可以使用 Parliament,但是如果您需要更简单的程序(由以前的维护人员构建) ,请尝试使用 Bree。

FeatureBullBeeAgenda
Backendredisredismongo
Priorities
Concurrency
Delayed jobs
Global events
Rate Limiter
Pause/Resume
Sandboxed worker
Repeatable jobs
Atomic ops
Persistence
UI
REST API
Optimized forJobs / MessagesMessagesJobs

Kudos for making the comparison chart goes to Bull maintainers.

Installation


Install via NPM

npm install agenda

您还需要一个工作的 Mongo 数据库(v3)来指向它

CJS / Module Imports


对于普通的 javascript 代码,只需使用默认的入口点

const Agenda = require("agenda");

对于类型脚本、 Webpack 或其他模块导入,使用 protocol/es 入口点:。

import Agenda, { Job, JobAttributesData } from 'agenda'

const mongoConnectionString = "mongodb://127.0.0.1/agenda";
const agenda = new Agenda({ db: { address: mongoConnectionString } });

interface CreateContact extends JobAttributesData {
  contactDetails: Contact // app-specific type
}

agenda.define<CreateContact>('CREATE CONTACT', async (job: Job<CreateContact>) => {
  const contactDetails = job.attrs.data.contactDetails; // type Contact
})

agenda.now<CreateContact>('CREATE CONTACT', {
  contactDetails: {...} // required attr
})

agenda.schedule<CreateContact>('in 5 minutes', 'CREATE CONTACT', {
  contactDetails: {...} // required attr
})

使用示例


const mongoConnectionString = "mongodb://127.0.0.1/agenda";

const agenda = new Agenda({ db: { address: mongoConnectionString } });

// 可以重写默认集合名称:
// const agenda = new Agenda({db: {address: mongoConnectionString, collection: 'jobCollectionName'}});

// 可以传递其他连接选项:
// const agenda = new Agenda({db: {address: mongoConnectionString, collection: 'jobCollectionName', options: {ssl: true}}});

// 可以传入一个现有的 mongodb 本机 MongoClient 实例
// const agenda = new Agenda({mongo: myMongoClient});

agenda.define("delete old users", async (job) => {
  await User.remove({ lastLogIn: { $lt: twoDaysAgo } });
});

(async function () {
  // IIFE 提供对异步/等待的访问
  await agenda.start();

  await agenda.every("3 minutes", "delete old users");

  //或者,也可以这样做:
  await agenda.every("*/3 * * * *", "delete old users");
})();
agenda.define(
  "send email report",
  { priority: "high", concurrency: 10 },
  async (job) => {
    const { to } = job.attrs.data;
    await emailClient.send({
      to,
      from: "example@example.com",
      subject: "Email Report",
      body: "...",
    });
  }
);

(async function () {
  await agenda.start();
  await agenda.schedule("in 20 minutes", "send email report", {
    to: "admin@example.com",
  });
})();
(async function () {
  const weeklyReport = agenda.create("send email report", {
    to: "example@example.com",
  });
  await agenda.start();
  await weeklyReport.repeatEvery("1 week").save();
})();

完整的文档


agenda 的基本控制结构是 agenda 的 一个实例。agenda 被映射到数据库集合,并从内部加载作业。

目录

  • 配置 agenda
  • Agenda 事件
  • 定义作业处理器
  • 创建作业
  • 管理作业
  • 启动作业处理器
  • 多任务处理器
  • 作业队列事件
  • 项目结构示例

配置 agenda

所有配置方法都是可链接的,这意味着您可以执行以下操作:

const agenda = new Agenda();
agenda
  .database(...)
  .processEvery('3 minutes')
  ...;

agenda 使用 人类通用的事件间隔 来确定时间间隔,它支持以下单位:

seconds, minutes, hours, days,weeks, months – assumes 30 days, years – assumes 365 days

更复杂的例子如下

agenda.processEvery("one minute");
agenda.processEvery("1.5 minutes");
agenda.processEvery("3 days and 4 hours");
agenda.processEvery("3 days, 4 hours and 36 seconds");

database(url, [collectionName])


指定 url 处的数据库。如果未指定集合名称,则使用 agendaJobs

agenda.database("localhost:27017/agenda-test", "agendaJobs");

也可以在实例化期间指定它。

const agenda = new Agenda({
  db: { address: "localhost:27017/agenda-test", collection: "agendaJobs" },
});

当连接到数据库时,agenda 将发出一个ready事件(参见“agenda事件”)。

当然,在不等待此事件的情况下调用 **agenda.start ()**仍然是安全的,

因为这是在内部处理的。

如果您正在使用 db 选项或调用数据库,那么在保存 作业 之前可能仍然需要监听。

mongo(dbInstance)


使用现有的 mongodb-native MongoClient/Db 实例。

这有助于合并到数据库的连接。

你可以用**.database 通过agenda** 为你处理连接。

您还可以在实例化期间指定它:

const agenda = new Agenda({ mongo: mongoClientInstance.db("agenda-test") });

请注意,MongoClient.connect ()返回一个 mongoClientInstance,从node-mongodb-native 3.0.0开始,而它过去常常返回一个 dbInstance,然后可以直接传递到 agenda

name(name)

设置 作业 集合中的 lastMofiedBy 字段的名称。如果您有多个作业 进程( agenda) ,并希望查看最后一次运行作业的作业队列,则可以使用

agenda.name(os.hostname + "-" + process.pid);

您也可以在实例化期间指定它

const agenda = new Agenda({ name: "test queue" });

processEvery(interval)

取一个字符串间隔,它可以是传统的 javascript 数字,也可以是一个字符串,比如 3 minutes

指定 agenda 查询数据库以查找需要处理的 作业 的频率。Agenda 在内部使用 setTimeout 来保证作业在正确的时间(接近 ~3 毫秒)运行。

降低频率将导致更少的数据库查询,但更多的 作业存储在内存中。

另外值得注意的是,如果作业队列关闭,

内存中存储的任何尚未运行的作业仍将被锁定,这意味着您可能需要等待锁定过期。

默认情况下,它是“5 seconds”。

agenda.processEvery("1 minute");

您也可以在实例化期间指定它

const agenda = new Agenda({ processEvery: "30 seconds" });

maxConcurrency(number)

采用一个数字,该数字指定在任何给定时刻可以运行的最大作业数。默认情况下,它是 20。

agenda.maxConcurrency(20);

您也可以在实例化期间指定它

const agenda = new Agenda({ maxConcurrency: 20 });

defaultConcurrency(number)

获取一个数字,该数字指定在任何给定时刻都可以运行的特定作业的默认数字。默认值是5。

agenda.defaultConcurrency(5);

您也可以在实例化期间指定它

const agenda = new Agenda({ defaultConcurrency: 5 });

lockLimit(number)

采用一个数字,该数字指定在任何给定时刻可以锁定的最大作业数。默认情况下,它为 0 表示无最大值。

agenda.lockLimit(0);

您也可以在实例化期间指定它

const agenda = new Agenda({ lockLimit: 0 });

defaultLockLimit(number)

取一个数字,该数字指定在任何给定时刻可以锁定的特定作业的默认编号。默认情况下,它为 0 表示无最大值。

agenda.defaultLockLimit(0);

您也可以在实例化期间指定它

const agenda = new Agenda({ defaultLockLimit: 0 });

defaultLockLifetime(number)

获取一个数字,该数字指定默认锁生存期(以毫秒为单位)。默认是10分钟。可以通过将 lockLifetime 选项指定到已定义的作业来覆盖此选项。

如果作业在 lockLifetime 之前完成(即在参数中指定返回的 Promise 解析/拒绝或 done 并调用 done(),则作业将解锁。如果作业崩溃或超时,锁定很有用。

agenda.defaultLockLifetime(10000);

您也可以在实例化期间指定它

const agenda = new Agenda({ defaultLockLifetime: 10000 });

sort(query)

接受指定用于查找和锁定下一个作业的排序查询的查询。

默认情况下,它是 { nextRunAt: 1, priority: -1 },就优先级而言,它遵循先进先出的方法。

disableAutoIndex(boolean)

可选。禁用在作业表上自动创建默认索引。默认情况下,Agenda 会创建一个索引,以在处理作业时优化其对 Mongo 的查询。

如果您想在特定用例中使用自己的索引,这将非常有用。

Agenda Events(Agenda 事件)

agenda 的实例将产生以下事件:

  • ready - 在成功打开 Agenda mongo 连接并创建索引时调用。如果您要向议程传递现有连接,则不需要侦听此连接,因为在创建索引之前,agenda.start() 不会解析。如果您使用的是 db 选项或调用数据库,则在保存作业之前可能仍需要侦听 ready 事件。agenda.start() 仍将等待连接打开。
  • error - 当 Agenda mongo 连接进程抛出错误时调用

Defining Job Processors (定义作业处理器)

在使用作业之前,必须定义其处理行为。

define(jobName, [options], handler)

定义名称为 jobName 的作业。当 jobName 的作业运行时,

它将被传递给 handler(job, done)。

为了保持异步行为,您可以在处理程序中提供 Promise 返回函数,

也可以将 done 作为第二个参数提供给处理程序。

如果在函数签名中指定了 done,则必须在处理作业时调用 done()。

如果你的函数是同步的或返回一个 Promise,你可以从签名中省略 done。

options 是一个可选参数,可以覆盖默认值。它可以采取以下措施:

  • concurrency:可以同时运行的j作业的最大数量(每个agenda实例)
  • lockLimit:该作业一次可以锁定的最大数量(每个agenda实例)
  • lockLifetime作业 保持锁定时间的间隔(以毫秒为单位)(有关详细信息,请参阅 multiple job processors)。一旦返回的 promise 解析/拒绝(或者如果 done,则在签名中指定并调用 done()),作业将自动解锁。
  • priority:(lowest|low|normal|high|highest|number)指定作业的优先级。优先级较高的作业将首先运行。请参阅下面的优先级映射
  • shouldSaveResult:布尔标志,指定作业的结果是否也应存储在数据库中。默认值为 false

优先级映射:

{
  highest: 20,
  high: 10,
  normal: 0,
  low: -10,
  lowest: -20
}

异步作业:

agenda.define("some long running job", async (job) => {
  const data = await doSomelengthyTask();
  await formatThatData(data);
  await sendThatData(data);
});

异步作业(使用 done):

agenda.define("some long running job", (job, done) => {
  doSomelengthyTask((data) => {
    formatThatData(data);
    sendThatData(data);
    done();
  });
});

同步作业:

agenda.define("say hello", (job) => {
  console.log("Hello!");
});

define() 就像一个赋值:如果 define(jobName, …) 被多次调用(例如,每次脚本启动时),最后一个调用中的定义将覆盖前一个调用。因此,如果在代码中仅定义一次 jobName,则多次执行该调用是安全的。

Creating Jobs(创建作业)

every(interval, name, [data], [options])

按给定的时间间隔运行 job name

(可选)可以传入数据和选项。每个都创建一个类型为 single 的作业,这意味着它只会在数据库中创建一个作业,即使该行运行多次也是如此。这使您可以将其放在可能多次运行的文件中,

例如可能时不时重新启动webserver.js。

interval 可以是人类可读的格式 String、cron 格式的 String 或 Number。

data 是一个可选参数,将传递给 job.attrs.data 下的处理函数。

options 是一个可选参数,将传递给 job.repeatEvery。为了使用此参数,还必须指定数据。

Returns the job.

agenda.define("printAnalyticsReport", async (job) => {
  const users = await User.doSomethingReallyIntensive();
  processUserData(users);
  console.log("I print a report!");
});

agenda.every("15 minutes", "printAnalyticsReport");

(可选)name 可以是作业名称数组,这便于在同一时间间隔内调度不同的作业。

agenda.every("15 minutes", [
  "printAnalyticsReport",
  "sendNotifications",
  "updateUserRecords",
]);

在本例中,每个都返回 作业 数组。

schedule(when, name, [data])

在指定定时间将 作业名称为 name 的计划运行一次。

when 可以是日期或字符串,例如明天下午 5 点。tomorrow at 5pm.

data 是一个可选参数,将传递给 job.attrs.data 下的处理函数。

agenda.schedule("tomorrow at noon", "printAnalyticsReport", { userCount: 100 });

可选地,name 可以是作业名称的数组,类似于 every 方法。

agenda.schedule("tomorrow at noon", [
  "printAnalyticsReport",
  "sendNotifications",
  "updateUserRecords",
]);

在本例中,每个都返回 作业 数组。

now(name, [data])

将立即运行一次作业名称为name的作业。

data 是一个可选参数,将传递给 job.attrs.data 下的处理函数。

返回 job。

agenda.now("do the hokey pokey");

create(jobName, data)

返回包含数据的 jobName 的实例。

这不会将作业保存在数据库中。请参阅下文,了解如何手动处理作业。

const job = agenda.create("printAnalyticsReport", { userCount: 100 });
await job.save();
console.log("Job successfully saved");

Managing Jobs(管理作业)

jobs(mongodb-native query, mongodb-native sort, mongodb-native limit, mongodb-native skip)允许您查询(然后对结果进行排序、限制和跳过)agenda jobs 数据库中的所有 作业。这些是完整的 mongodb 原生 查找、排序、限制和跳过命令。有关详细信息,请参阅 mongodb-native 的文档。

const jobs = await agenda.jobs(
  { name: "printAnalyticsReport" },
  { data: -1 },
  3,
  1
);
// 使用 job(见下文)

cancel(mongodb-native query)

取消与传递的 mongodb-native 查询匹配的任何 jobs ,并将其从数据库中删除。返回一个 Promise,该 Promise 解析为已取消的作业数,或在出错时拒绝。

const numRemoved = await agenda.cancel({ name: "printAnalyticsReport" });

此功能也可以通过首先使用 agenda.jobs() 从数据库中检索所有作业来实现,遍历生成的数组并在每个作业上调用 job.remove()。但是,对于此用例,最好使用 agenda.cancel(),因为这可以确保操作是原子的。

disable(mongodb-native query)

这个功能允许你根据给定的MongoDB查询条件去临时禁用一批任务。被禁用的任务不会按计划执行,直到你再次启用它们。这对于暂时停止某类任务,或者在特定条件下临时避免任务执行非常有用。

const numDisabled = await agenda.disable({ name: "pollExternalService" });

与 agenda.cancel() 类似,此功能可以通过 agenda.jobs() 和 job.disable() 的组合来实现

enable(mongodb-native query)

启用与传递的 mongodb-native 查询匹配的任何作业,从而允许作业处理器运行任何匹配的作业。

const numEnabled = await agenda.enable({ name: "pollExternalService" });

类似于agenda.cancel() ,这个功能可以通过 **agenda.jobs ()**和 job.enable () 的组合来实现

purge()

移除数据库中未定义行为的所有作业。如果更改定义名称并希望删除旧作业,则使用。返回一个解析已删除作业的数目或拒绝出错的承诺。

重要说明:在完成定义所有作业之前,不要运行此操作。如果你这样做,你将破坏你的工作数据库。

const numRemoved = await agenda.purge();

Starting the job processor(启动作业处理器)

若要获取从数据库开始处理 作业的 agenda,必须启动它。

这将安排一个时间间隔(基于 processEvery)来检查新作业并运行它们。您也可以停止队列。

start

启动job队列处理,每次检查进程,查看是否有新作业。必须在 processEvery 之后和任何作业计划(例如 every)之前调用。

stop

停止作业队列处理。解锁当前正在运行的作业

这对于正常关闭非常有用,这样当前正在运行/抓取的作业将被放弃,以便其他作业队列可以抓取它们/在作业队列再次启动时解锁它们。下面是一个示例,说明如何进行正常关闭。

async function graceful() {
  await agenda.stop();
  process.exit(0);
}

process.on("SIGTERM", graceful);
process.on("SIGINT", graceful);

drain

停止 作业队列处理并等待所有当前 作业 完成。

这对于正常关闭非常有用,以便在关闭之前完成当前正在运行/抓取的作业。

下面是一个示例,说明如何进行正常关闭。

async function graceful() {
  await agenda.drain();
  process.exit(0);
}

process.on("SIGTERM", graceful);
process.on("SIGINT", graceful);

close(force)

关闭数据库连接。您通常不必这样做,但它可能对测试目的有用。

使用 force boolean,您可以强制关闭连接。

阅读 MongoDB Driver API 的更多内容Node.js

await agenda.close({ force: true });

Multiple job processors(多个作业处理器)

有时,您可能希望让多个节点实例/计算机从同一队列进行处理。Agenda 支持锁定机制,以确保多个队列不会处理相同的作业。

您可以通过在定义作业时将 lockLifetime 指定为间隔来配置锁定机制。

agenda.define("someJob", { lockLifetime: 10000 }, (job, cb) => {
  // Do something in 10 seconds or less...
});

这将确保在接下来的 10 秒内没有其他 作业处理器(包括此处理器)尝试再次运行作业。如果作业运行时间特别长,则需要指定更长的 lockLifetime。

默认情况下为 10 分钟。通常,您不应该有一个运行 10 分钟的作业,因此,如果作业队列在作业解锁之前崩溃,这确实是保险。

当作业完成时(即在签名中指定了返回的 promise 解析/拒绝或 done 并调用了 done(),它将自动解锁。

Manually working with a job(手动处理作业)

作业实例具有多个实例方法。所有 muting 方法之后都必须调用 await job.save() 才能将更改保存到数据库中。

repeatEvery(interval, [options])

指定job应重复的时间间隔。job在定义时也以配置的时间间隔运行,即“现在运行并按时间间隔运行”。

  • interval 可以是人类可读的格式 String、cron 格式的 String 或 Number。

  • options 是一个可选参数,包含:

  • options.timezone:应该是 moment-timezone 接受的字符串,并且在使用 cron 字符串格式的间隔时会考虑。

  • options.skipImmediate:true |false(默认值):将此项设置为 true 将跳过立即运行。第一次运行将仅在配置的时间间隔内进行。

  • options.startDate:作业首次运行的日期应等于或晚于开始日期。

  • options.endDate:作业不应在 endDate 之后重复的日期。作业可以在结束日期本身运行,但不能在此日期之后运行。

  • options.skipDays:人类可读的字符串(“2 天”)。每次运行后,它将跳过“skipDays”的持续时间

job.repeatEvery("10 minutes");
await job.save();
job.repeatEvery("3 minutes", {
  skipImmediate: true,
});
await job.save();
/*
设定一个每3分钟执行一次的任务,
并且首次执行时不立即执行,
而是等待3分钟后开始第一次执行;
同时,将此任务的配置信息保存到数据库中,以保证任务调度的持久性。
*/
job.repeatEvery("0 6 * * *", {
  timezone: "America/New_York",
});
await job.save();

repeatAt(time)

指定job应重复的时间。可能的值

job.repeatAt("3:30pm");
await job.save();
/*
总的来说,这两行代码的作用是:
设置一个任务在每天下午3点30分执行,
并确保这一执行时间点的信息会被保存到数据库中,
使得即使应用重启也能按照设定的时间点继续执行任务。
然而,repeatAt 方法并不意味着任务会在每天的同一时间重复执行,
除非你在代码中额外设置循环重复逻辑。
*/

schedule(time)

指定作业下次运行的时间。

job.schedule("tomorrow at 6pm");
await job.save();

priority(priority)

指定作业的优先级权重。可以是上述优先级表中的数字或字符串。

job.priority("low");
await job.save();

setShouldSaveResult(setShouldSaveResult)

指定作业的结果是否也应存储在数据库中。默认值为 false。

job.setShouldSaveResult(true);
await job.save();

作业返回的数据将在成功后在结果属性上可用,并再次从数据库中检索,例如通过 agenda.jobs(…)或通过success job event)。

unique(properties, [options])

确保此作业仅存在一个具有指定属性的实例

options 是一个可选参数,可以覆盖默认值。它可以采取以下措施:

insertOnly:如果作业已存在,布尔值将阻止任何属性保留。默认值为 false。

job.unique({ "data.type": "active", "data.userId": "123", nextRunAt: date });
await job.save();

重要提示:为了保证唯一性并避免MongoDB使用率过高,请确保在使用的字段上创建一个唯一的索引,例如上面示例中的name,data.type和data.userId。

fail(reason)

将 job.attrs.failedAt 设置为 now,并将 job.attrs.failReason 设置为 reason。

(可选)reason 可以是错误,在这种情况下,job.attrs.failReason 将设置为 error.message

job.fail("insufficient disk space");
// or
job.fail(new Error("insufficient disk space"));
await job.save();

run(callback)

运行给定的作业并在完成后调用 callback(err, job)。通常,您永远不需要手动调用它。

job.run((err, job) => {
  console.log("I don't know why you would need to do this...");
});

save()

将 job.attrs 保存到数据库中。返回解析到 作业 实例的 Promise,或在出错时拒绝。

try {
  await job.save();
  console.log("Successfully saved job to collection");
} catch (e) {
  console.error("Error saving job to collection");
}

remove()

从数据库中删除作业。返回一个 Promise,解析为已删除的作业数,或在出错时拒绝

try {
  await job.remove();
  console.log("Successfully removed job from collection");
} catch (e) {
  console.error("Error removing job from collection");
}

disable()

禁用作业。即将到来的运行将不会执行。

enable()

如果作业之前被禁用,则启用该作业。即将到来的运行将执行。

touch()

重置作业上的锁定。用于指示作业在运行时间很长时作业未超时。该调用将返回一个承诺,该承诺在续订作业的锁定时解析。

agenda.define("super long job", async (job) => {
  await doSomeLongTask();
  await job.touch();
  await doAnotherLongTask();
  await job.touch();
  await finishOurLongTasks();
});

Job Queue Events()

agenda 的实例将发出以下事件:

  • start - 在作业开始之前调用
  • start:job name - 在指定作业开始之前调用
agenda.on("start", (job) => {
  console.log("Job %s starting", job.attrs.name);
});
  • complete - 在作业完成时调用,无论作业是成功还是失败
  • complete:job name - 在作业完成时调用,无论作业是成功还是失败
agenda.on("complete", (job) => {
  console.log(`Job ${job.attrs.name} finished`);
});
  • success - 在作业成功完成时调用
  • success:job name- 在作业成功完成时调用
agenda.on("success:send email", (job) => {
  console.log(`Sent Email Successfully to ${job.attrs.data.to}`);
});
  • fail - 在作业引发错误时调用
  • fail:job name - 当作业引发错误时调用
agenda.on("fail:send email", (err, job) => {
  console.log(`Job failed with error: ${err.message}`);
});

Example Project Structure(项目结构示例)

Agenda 将仅处理它有定义的作业。这使您可以有选择地选择给定议程将处理的作业。

请考虑以下项目结构,它允许我们与代码库的其余部分共享模型,并指定工作线程处理的作业(如果有的话)。

- server.js
- worker.js
lib/
  - agenda.js
  controllers/
    - user-controller.js
  jobs/
    - email.js
    - video-processing.js
    - image-processing.js
   models/
     - user-model.js
     - blog-post.model.js

Sample job processor (eg. jobs/email.js)

let email = require("some-email-lib"),
  User = require("../models/user-model.js");

module.exports = function (agenda) {
  agenda.define("registration email", async (job) => {
    const user = await User.get(job.attrs.data.userId);
    await email(
      user.email(),
      "Thanks for registering",
      "Thanks for registering " + user.name()
    );
  });

  agenda.define("reset password", async (job) => {
    // Etc
  });

  // More email related jobs
};

lib/agenda.js

const Agenda = require("agenda");

const connectionOpts = {
  db: { address: "localhost:27017/agenda-test", collection: "agendaJobs" },
};

const agenda = new Agenda(connectionOpts);

const jobTypes = process.env.JOB_TYPES ? process.env.JOB_TYPES.split(",") : [];

jobTypes.forEach((type) => {
  require("./jobs/" + type)(agenda);
});

if (jobTypes.length) {
  agenda.start(); // Returns a promise, which should be handled appropriately
}

module.exports = agenda;

lib/controllers/user-controller.js

let app = express(),
  User = require("../models/user-model"),
  agenda = require("../worker.js");

app.post("/users", (req, res, next) => {
  const user = new User(req.body);
  user.save((err) => {
    if (err) {
      return next(err);
    }
    agenda.now("registration email", { userId: user.primary() });
    res.send(201, user.toJson());
  });
});

worker.js

require("./lib/agenda.js");

现在,您可以在项目中执行以下操作:

node server.js

启动一个没有JOB_TYPES的实例,使您能够处理作业,但不会浪费资源处理作业。

JOB_TYPES=email node server.js

允许您的 http 服务器处理电子邮件作业。

JOB_TYPES=email node worker.js

启动处理电子邮件作业的实例。

JOB_TYPES=video-processing,image-processing node worker.js

启动处理视频处理/图像处理作业的实例。适合大型服务器。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值