How to run cron job only when making a get request & not everytime we start the server - cron

I want the cron job to get triggered only when we make a get request, it does for the first time, but if I save it will re-run again.
The code does not run whenever the server starts or restarts but as soon as I hit that specefic endpoint, It will run every time the server re-starts.
startTime = new Date().getTime();
numberOfMinutes = 10;
#Cron(CronExpression.EVERY_MINUTE, {
name: 'myJob',
})
async getParisAirQuality() {
this.logger.verbose(`Getting paris air quality`);
const result = await this.getCityAirQuality({
latitude: '48.856613',
longitude: '2.352222',
});
const airQuality = new this.airQualityModel({
result,
datetime: new Date().toLocaleString(),
});
await airQuality.save();
this.closeJob();
return {
result: airQuality.result,
datetime: new Date().toLocaleString(),
};
}
closeJob() {
const job = this.schedulerRegistry.getCronJob('myJob');
const endTime = this.startTime + 1000 * 60 * Number(this.numberOfMinutes);
if (job.lastDate().getTime() >= endTime) {
job.stop();
}
}

Related

NodeJs parallel request in a loop too slow

so I have this feature that I am working on that takes an object (Over 10k items) picks an item from this object, sends it to an api, which process it then give a response, then proceeds to the next item.
Currently using the async library, the mapLimit method and it works as aspected.
But my problem is that it’s takes too long to loop through the entire dataset cause of the length.
This feature is suppose to be a continual process, once the entire object is iterated, wait for few seconds then do the same thing again.
I tried forking a child_process for this, broke the objects into chunks and created a process for each chunks till it was completed. This worked well as intended but the memory consumption was massive other processes on the server failed as a result of lack of available memory, even after exiting the process after it was completed.
Please how do I achieve this at a faster rate?
I use this to get the list of wallets.
getListofWallet = async () => {
try {
const USDT = await usdt.query(sql`
SELECT * FROM USDT ORDER BY id DESC;
`);
let counter = 0;
let completion = 0;
async.mapLimit(USDT, 6, async (user) => {
let userDetail = {
email: user.email,
id: user.user_id,
address: user.address
}
try {
await this.getWalletTransaction(userDetail);
completion++;
} catch (TronGridException) {
completion++;
console.log(":: A TronGrid Exception Occured");
console.log(TronGridException);
}
if (USDT.length == completion || USDT.length == (completion-5)) {
setTimeout(() => {
this.getListofWallet();
}, 60000);
console.log('~~~~~~~ Finished Wallet Batch ~~~~~~~~~');
}
}
);
} catch (error) {
console.log(error);
console.log('~~~~~~~Restarting TronWallet File after Crash ~~~~~~~~~');
this.getListofWallet();
}
}
Then I use this to process to data sent and perform the neccessary action.
getWalletTransaction = async (walletDetail) => {
const config = {
headers: {
'TRON-PRO-API-KEY': process.env.api_key,
'Content-Type': 'application/json'
}
};
const getTransactionFromAddress = await axios.get(`https://api.trongrid.io/v1/accounts/${walletDetail.address}/transactions/trc20`, config);
const response = getTransactionFromAddress.data;
const currentTimeInMillisecond = 1642668127000; //1632409548000
response.data.forEach(async (value) => {
if (value.block_timestamp >= currentTimeInMillisecond && value.token_info.address == "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") {
let doesHashExist = await transactionCollection.query(sql`SELECT * FROM transaction_collection WHERE txhash=${value.transaction_id};`);
if (doesHashExist.length == 0) {
if (walletDetail.address == value.to) {
const checkExistence = await CryptoTransactions2.query(sql`
SELECT * FROM CryptoTransaction2 WHERE txHash=${value.transaction_id};
`);
if (checkExistence.length == 0) {
const xCollection = {
collection: "CryptoTransaction2",
queryObject: {
currency: "USDT",
sender: ObjectID("60358d21ec2b4b33e2fcd62e"),
receiver: ObjectID(walletDetail.id),
amount: parseFloat(tronWeb.fromSun(value.value)),
txHash: value.transaction_id,
description: "New wallet Deposit " + "60358d21ec2b4b33e2fcd62e" + " into " + value.to,
category: "deposit",
createdAt: new Date(),
updatedAt: new Date(),
},
};
await new MongoDbService().createTransaction(xCollection);
//create record inside cryptotransactions db.
await CryptoTransactions2.query(sql`INSERT INTO CryptoTransaction2 (txHash) VALUES (${value.transaction_id})`)
});
}

Run Nodejs App Every 6 Hours with Aysnc Await

I want to run a Script every 6 Hours
const { IgApiClient } = require("instagram-private-api")
const ig = new IgApiClient()
const USERNAME = "abc"
const PASSWORD = "xyz"
ig.state.generateDevice(USERNAME)
const main = async () => {
var birthday = new Date(2069, 05, 14);
var today = new Date();
birthday.setFullYear(today.getFullYear());
if (today > birthday) {
birthday.setFullYear(today.getFullYear() + 1);
}
var daystill = Math.floor((birthday - today) / (1000*60*60*24))
await ig.simulate.preLoginFlow()
await ig.account.login(USERNAME, PASSWORD)
process.nextTick(async () => await ig.simulate.postLoginFlow())
await ig.account.setBiography(`${daystill} Days till my Birthday, Today is ${new Date().getDate()}/${new Date().getMonth()}/${new Date().getFullYear()}. (AutoGenerated)`)
}
main()
instagram-private-api
About Script: update my Instagram Bio with Async Await
Problem / Goal:
I Tried using node-cron, but It returns some Error (I think Async is causing the Problem), I also tried while loops and setInterval()s
I want this Script/File to run every 6 Hours, I have a heroku account (if that helps)
Error when i use node-cron:
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
Code for node-cron:
cron.schedule('* * * * *', () => { // this is not every 6hrs
const main = async () => {
//same as above
}
main()
})
Doing it the async await way as the title says.
// used to measure time
import { performance } from 'perf_hooks';
const interval = 1000; // in ms
(async function main(){
let start_time = performance.now();
// do stuff
let stop_time = performance.now();
let timeout = interval - (stop_time - start_time);
setTimeout(main, timeout);
})();
edit:
To explain the syntax behind the main function.
()(); will automatically call the function inside of first braces on script start.

Crone Task runs multiple times in a single interval NodeJS

I have the problem that in the server the Crone Task is running X4 number of times for each scheduled interval, not only the logs are shown x4 but also the API is called 4 times.
const taskCron = nodeCron.schedule('*/1 * * * *', function () {
const timeZone = moment.tz('America/Mexico_City').format();
const currentDate = splitDate(timeZone);
const currentTime = splitTime(timeZone);
console.info(`EXECUTING CRON TASK ${currentDate} ${currentTime}`);
campaign.find(
{ hour_to_send: currentTime, date_to_send: { $gte: currentDate, $lte: currentDate}}
).exec().then(data => {
console.log('number of campaigns programmed: ' + data.length);
const campaignsMapped = data.map(campaign => {
return {
id: campaign._id
};
});
const secretBulk = 'secret-bulk';
const bodyRequest = {
campaignsList: campaignsMapped,
key: secretBulk
};
if (campaignsMapped.length > 0) {
axios.post(url_bulk, bodyRequest, {})
.then(data => {
console.info(data.status);
})
.catch(error => {
console.error(error.code);
});
}
}).catch(error => {console.log(error)});
function splitDate(date) {
return date.slice(0, 10);
}
function splitTime(date) {
return date.slice(11, 16) + ':00';
}
}, {scheduled: false});
taskCron.start();
Use the library node-cron npm
The server is derived from centos Oracle version, the program runs in a docker container official Node JS image version 10, docker Docker version 19.03.11, build 42e35e61f3, It is worth mentioning that on my local machine with windows 10 this behavior does not happen.

How to send email after a one week in nodejs

I created a script: when a user signups our app, then I will send a welcome email, then I want after one another will be send.
Note: Now cron job runs every minute, I will change it later.
var job = new CronJob('* * * * *', function() {
console.log('Cron Job is happen on',Date());
emailSend()
}, null, true, '');
function emailSend(){
SingUpDate = something
comapredate = today-7
if(comparedate == signupdate){
sendEmail()
}
else{
return false
}
}
I want to know about how to stop cron after a week.
You could have your emailSend function remove its own cron job:
var job = new CronJob('* * * * *', function () {
console.log('Cron Job will happen on', Date())
emailSend()
}, null, true, '')
// you will need to start the job:
job.start()
function emailSend () {
SingUpDate = something
comapredate = today-7
if (comparedate == signupdate) {
sendEmail()
// and then stop it here:
job.stop()
} else {
return false
}
}
Or you can schedule it for the specific date that you want:
const date = new Date();
date.setDate(date.getDate() + 7)
const job = new CronJob(date, () => {
console.log(`Scheduled job for ${date} running at ${new Date()}`)
emailSend()
}, null, true, '')
job.start()

Agenda not running jobs on schedule

I am trying to use agenda to schedule jobs at a certain date and time, but the jobs are not running when the specified date is reached.
This is how I'm creating the job:
agenda.create(type, data)
.schedule(new Date(startDate))
.repeatEvery('11 21 * * *', {timezone: 'Europe/Bucharest'})
.save();
This is how I start agenda:
const Agenda = require('agenda');
const mongoDB = process.env.DB_PATH;
const mongoConnectionString = mongoDB;
let agenda = new Agenda({db: {address: mongoConnectionString, collection: 'jobs'}});
let jobTypes = process.env.JOB_TYPES ? process.env.JOB_TYPES.split(',') : [];
jobTypes.forEach(function(type) {
require('./jobs/' + type)(agenda);
});
if(jobTypes.length) {
agenda.on('ready', function() {
console.log('agenda start')
agenda.start();
});
}
function graceful() {
agenda.stop(function() {
process.exit(0);
});
}
process.on('SIGTERM', graceful);
process.on('SIGINT' , graceful);
export default agenda;
This is an example with a job that didn't start on the scheduled date:
Is there something I'm doing wrong?
EDIT:
The job is triggered if I do schedule(new Date()), but it won't using a defined date.

Resources