Nestjs Schedule build uninterrupted cron running - nestjs

I am using nestjs schedule for my cron but I have a question.
How can I stop cron without interrupting the cron that are currently running to do a build and change the code? Or any suggestion or strategy?

I faced the same problem before.
I saved all cron jobs to a dedicated table.
I made a service to run and stop a cron job.
Each time the server restarts, this service finds the jobs from the table and restored them.
For example:
#Injectable()
export class AppJobService implements OnApplicationBootstrap {
constructor(
private schedule: SchedulerRegistry
) {}
async onApplicationBootstrap() { // <- Nestjs hook invoked when the app bootstrapped
const jobs = await Job.find(); // the jobs are all saved in `Job` table.
jobs.forEach(job => {
const cron = new CronJob(job.time, () => {}) // You can define the handler for each job type
this.schedule.addCronJob(job.name, cron);
cron.start();
});
}
}
Hope this helps you.

Related

Send a PUT request from all accounts in the database after every 24hours in Production

I have deployed my website, in my website user have to complete 10 orders every day, i want to reset orders at 9am everyday. i am using MERN stack. how to reset orders ? i am thinking of sending put requests that modifies user orders to 0 at 9am everyday.
import schedule from 'node-schedule'
const { currentUser } = useSelector((state) => state.user) //using Redux to fetch current user
schedule.scheduleJob('0 9 * * *', async () => {
try {
await axios.put(`/details/${currentUser._id}`, {
dailyOrders: 0,
})
} catch (err) {
console.log(err)
}
})
I have tried using node-cron but that didn't work well. it will work only if the user is logged in to the account and have opened the site all the time. If he closes site , node cron will not work.
I have deployed my website! and tried using pm2 start myapi
There are potentially multiple options, depending on your architecture and the complexity of your backend servers. Also, I strongly believe that this is a task to be completed on the backend servers rather than the client:
You would need a database query to reset all users' orders
This could be a secure route (e.g accessible only to admins through authentication)
Here are some examples of potential solutions depending on your architecture:
If you are using cloud deployment (e.g AWS) you could set up a lambda function to accomplish this and call it on a given schedule via EventBridge (this is basically a serverless cron job)
If you have only one instance of the backend server running you could set up a cron job on that instance (thinking of node-cron job). However, beware of server downtimes and/or multiple servers running at the same time
In a nutshell, there are many ways to accomplish this (it's not one size fit all situation) however this has to be done on the backend servers

NextJs how to call api once only when its deployed on server

I am working on a project in which I can create new files and also can move them to the trash. Also, have the functionality to automatically delete these trashed files after a specific time (in my case it's 30 days). I have searched on the internet and found this node-schedule. I have created an API that starts the scheduler every day, but the problem is, every time I deploy the application I need to hit this API to run the scheduler. here is my code
const schedule = require('node-schedule');
const moment = require('moment');
export default async function handler(req, res) {
const rule = new schedule.RecurrenceRule();
rule.hour = 0;
const job = schedule.scheduleJob(rule, function () {
// delete files older than 30 days
});
res.send(200)
}
My question is, Is there any way to get rid of hitting API every time I deploy the application? or any better Idea to do this task?

How do I run cron/scheduled task in Nextjs 9?

I'm building an app with Nextjs and I'm using pages/api directory for my api endpoints. The server entry/root is hidden for me. How do I immediately run the scheduled task with node-cron when my app is deployed then?
I had the same problem. What you can do are scheduled tasks with the node-cron library. You have to put your task which you want to schedule in your next.config.js file like so:
/** #type {import('next').NextConfig} */
const cron = require('node-cron');
cron.schedule('* * * * *', function () {
console.log('Say scheduled hello')
});
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig
It is recommended that you keep the next.config.js pretty simple as stated here: https://github.com/vercel/next.js/issues/5318#issuecomment-540629772
So if using a custom server inside next.js is not recommended either, the best solution would be to use a third party or boot up a second server
You can use their Custom Server hook to include your task scheduling logic during the server initialization. But keep in mind that this is not recommended:
Before deciding to use a custom server please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like serverless functions and Automatic Static Optimization.

How to define task in node-celery ?

I am using node-celery.
I just need to implement scheduling task so that Task can run on the background at the specific time.
I am confused how can I define my task, currently I am defining task at the same file where I am implementing node-celery.
const celery = require('node-celery');
let client = celery.createClient({
CELERY_BROKER_URL: 'amqp://guest:guest#localhost:5672//',
CELERY_RESULT_BACKEND: 'amqp://'
});
In the above code, I just require node-celery and then created a client for amqp.
Now I have to connect client and then call my task send_batch_email_using_mailgun with some parameter.
client.on('connect', function() {
client.call('send_batch_email_using_mailgun', {
campaign_data: campaign_data,
subject: subject,
template: template
}, {
eta: new Date(Date.now() + 120000)
});
});
Here _send_batch_email_using_mailgun_ is the task which is defined below the code in the same file with some parameter.
I want that my function _send_batch_email_using_mailgun_ should be called after a certain time. My code is not working I think I have to define my task function elsewhere but I don't know where to define them.
Do I need to create my task in python file? If yes then how can I import them in my js file?
You can start small and use the setInterval() api to make a scheduled task.
Let's say your task is to send email to all users.
Define it in a function like this:
function sendScheduledEmails() {
// Get all the emails
// Send emails with your provider
}
Test it if it works by calling the func, but just putting it and running your server once:
sendScheduledEmails()
When you see your function is working, use the api:
setInterval(sendScheduledEmails, 120000)
Check if your app is doing the task within the intervals. Once you see it's working, you can look into other modules and further tweak it.
If you want to take action after something happens. Let's say you want to send email after a user is registered.
Then when the user registers, you can emit an event like this:
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// User registered
// Redirect to success page
myEmitter.emit('userRegistered');
This will fire an event everytime that action happens, and you can listen to it.
Then in your code you can do:
myEmitter.on('userRegistered', function() {
setInterval(sendScheduledEmails, 120000)
})
TL;DR
its a python function.
for more info see the docs
details
the lingo here is a bit confusing so i'll try to clear it up:
your celery client is actually connecting to the broker (which is the task queue).
The broker will recieve a message with the function name and parameters you wish to run.
The celery worker is a python process which pulls the messages from the broker and then executes the function you requested.
The implementation of send_batch_email_using_mailgun only needs to be known to the celery worker.

write polling service in node.js with sails.js framework

i have project in sails.js, i want to write a polling service that check some record in some interval and after that send email. my example code is:
module.exports.bootstrap = function(cb) {
cb();
var refresh = function() {
setTimeout(doWork, //someInterval);
};
var doWork = function() {
if (//check some condition) {
sendEmail();
}
refresh();
};
doWork();
}
i use pm2 libary and start my project with cluster mode. example code is:
pm2 start app.js -i 4
this command run app.js in cluster mode with 4 process.
the problem is my polling service run in all process because i run my polling service in config/bootstrap.js file and this is very bad.
my question is how can i run my service once in all process?
You can check if process is master and then run script only on that case.
var cluster = require('cluster');
if(cluster.isMaster) // rest of your service...
But for me... This is strange logic... You should queue your tasks to shared db, and when task is pooled remove it from it etc.

Resources