Автор оригинала: Miguel Kouam.
Если вы когда-либо хотели расписать функции в вашем приложении Node.js и не смогли найти простой способ выполнить это, то вы найдете эту статью очень полезную.
Исходный код: https://github.com/migueLedric/agenda-server-starter.
Я наткнулся Agenda.js работая над личным проектом (приложение Rideshare). Я искал обновлять статус автоматически, отправлять напоминания пассажирам за несколько часов до времени отправления, подскажите их оставлять отзыв после поездки и многое другое.
Я не хотел пользоваться заданиями CRON, но вместо этого есть все в Nodejs и иметь возможность обновлять (или удалять) эти задания, такие как обновление простого документа базы данных.
Запланированные задания сохраняются как документы в вашей коллекции «Работа». Вы можете редактировать запланированное время работы или удалить его, чтобы он вообще не работает.
У каждого документа есть Nextrunat Свойство, именно дата и время выполнятся функция задания. Вы можете выполнить любые операции Mongodb Crud в документе.
Здесь я прохожу тебя через настройку повестки дня-стартера-сервера.
Файлы:
controllers/ rideController.js jobs/ - agenda.js jobs_list/ - archiveRideJob.js routes/ - routes.js - server.js - package.json - .env
Package.json.
{ "name": "agenda-server-starter", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "agenda": "^3.0.0", "dotenv": "^8.2.0", "express": "^4.17.1", "express-mongo-db": "^2.0.4", "mongodb": "^3.5.3" }, "devDependencies": { "nodemon": "^2.0.2" } }
Поскольку это не учебное пособие по поводу создания сервера Express.js, я собираюсь прыгнуть прямо в то, как настроить agenda.js, чтобы расписание рабочих мест/функций.
Для начала необходимо создать файл конфигурации повестки дня, который подключается к вашей базе данных и выполняет определенные задания.
Работа/agenda.js.
let Agenda = require("agenda"); // set the collection where the jobs will be save // the collection can be name anything let url = process.env.DB_URL // DB_URL="mongodb://127.0.0.1:27017/test-db" let agenda = new Agenda({ db: {address: process.env.DB_URL, collection: 'jobs'}}); // list the different jobs availale throughout your app let jobTypes = ["archiveRideJob"]; // loop through the job_list folder and pass in the agenda instance to // each job so that it has access to its API. jobTypes.forEach( type => { // the type name should match the file name in the jobs_list folder require('./jobs_list/'+ type)(agenda); }) if(jobTypes.length) { // if there are jobs in the jobsTypes array set up agenda.on('ready', async () => await agenda.start()); } let graceful = () => { agenda.stop(() => process.exit(0)); } process.on("SIGTERM", graceful); process.on("SIGINT", graceful); module.exports = agenda;
.env.env.
DB_URL="mongodb://127.0.0.1:27017/test" MONGO_URL="mongodb://127.0.0.1:27017" DB_NAME="test"
Теперь давайте определим нашу работу.
Хотя вы можете определить свою работу внутри только одного файла, разделение каждая задание в его файле позволяет легко масштабироваться или иметь больше смысла для меня.
В повестке дня вы определяете работу, а затем вы можете запланировать или обработать их, как вы хотите на протяжении всего вашего приложения.
Давайте посмотрим на файл работы ArchiverideJob.
Работа/рабочие места/archiveridejob.js
let MongoClient = require("mongodb").MongoClient; module.exports = (agenda) => { agenda.define("archive ride", (job, done) => { console.log("Archiving ride ...") // to be able to that you need to grab the ride id which is on the job document in the jobs collection in the database. // first let's connect to mongo db server //MONGO_URL="mongodb://127.0.0.1:27017" let client = new MongoClient(process.env.MONGO_URL) client.connect((err) => { if(!err) { console.log('connection to db successful'); // connect to the database // DB_NAME="test" let db = client.db(process.env.DB_NAME); // get the data passed when scheduling the job in the controller let rideId = job.attrs.data.rideId; db.collection('rides').findOneAndUpdate({_id: rideId}, { $set: { status: 'expired' }}, (error) => { if(!error) { console.log('Successfully archived ride. rideId: ', rideId); client.close(); done(); } else { console.log("Error archiving ride ID: ", rideId); console.log(error); client.close(); done(); } }) } else { console.log(err); client.close(); done(); } }) }) }
Здесь я использую родной драйвер Node.js для MongoDB (не мангусты ORM). Если вы используете Mongoose, то вам нужно импортировать свои модели в этом файле и выполнять свои операции CRUD.
Итак, во-первых, мы определяем нашу задачу «Архив езды».
agenda.define('archive ride', function(job, done) { // your code goes here })
Далее я создаю подключение к моей базе данных.
let client = new MongoClient(process.env.MONGO_URL) ... ... let db = client.db(process.env.DB_NAME);
Опять же, если вы используете ORM (Object Relational Mapper), как Mongoose, то вам не нужно создавать это соединение.
db.collection('rides').findOneAndUpdate({_id: rideId}, { $set: { status: 'expired' }}, function (error) { if(!error) { .... .... done(); } ... ... })
Это это для определения работы.
Теперь нам нужно запланировать нашу работу, когда пользователь создает поездку. Мы делаем это в нашем контроллере.
Контроллеры/RideController.js.
let agenda = require('../jobs/agenda'); module.exports = { postRide: (req, res) => { // you ride data when someone posts a ride let myRide = { departureDate: new Date(Date.now()), // aslo the archive date rideData: "Some data" } // get the database object from the request object see server.js let db = req.db; // create a new ride document the ride data db.collection('rides').insertOne({...myRide}, (ride, err) => { if(!err) { // if the ride is successfully saved in the database, schedule a job with a unique id in the job collection agenda.schedule( myRide.departureDate, // date the function will execute "archive ride", { rideId: ride.insertedId } // add additional information to be accessed by the job function: job.attrs.data.rideId; ); res.send("Hello World!") } else { console.log(err) res.send("Hello Error!") } }) } }
Есть много способов планирования и выполнения рабочих мест с помощью agenda.js. Здесь я использую agenda.schedule (); Чтобы запланировать работу, которая должна быть выполнена в будущей дате, которую я указал. В качестве альтернативы вы можете использовать Pogenda.Now () (), чтобы немедленно выполнить задание. Перейдите к документации для [других методов]. (Https://github.com/agenda/agenda#creating-jobs).
Если вам интересно промежуточное программное обеспечение подключения к базе данных, я добавил этот пакет NPM Экспресс-Mongo-DB Отказ (Очень необязательно)
Вот как настроены маршруты и сервер:
маршруты/маршруты
const router = require("express").Router(); // import the controllers/functions to run when requesting a specific end point let rideController = require('../controllers/rideController'); // run the function postRide in rideController when requestion "/" endpoint router.get('/', rideController.postRide); module.exports = router; // to be imported in server.js and used with route middleware
server.js.
let express = require('express') require('dotenv').config(); // make environment variables available throughout the app let expressMongoDB = require('express-mongo-db') // attach the mongodb instance to the request object // importing routes let indexRoutes = require('./routes/routes'); let app = express(); let port = 3000 // connects to the database and attach a db object to the request object app.use(expressMongoDB(process.env.DB_URL)) // e.g: DB_URL="mongodb://127.0.0.1:27017/test" app.use('/', indexRoutes) app.listen(port, () => { console.log(`Server is listenung on port ${port}...`) })
Вот и все. Если у вас есть вопросы или предложения, оставьте комментарий ниже.