How to Access SchedulerRegistery ID in Nest Js - cron

I am using #nestjs/schedule for scheduling tasks. Sample code for scheduling are as follows
async scheduleCron(cronId: any, day: any){
let cronTime = '0 0 '+day+' * *';
const job = new CronJob('* * * * *', () => {
this.postOrder();
});
this.schedulerRegistry.addCronJob(cronId, job);
job.start();
}
Here cronId is my custom Id which I passed to identify between different crons. Now when postOrder is called by a specific cronjob I want to access cronId of cronjob so that I know which cronjob had executed and based on that I can make appropriate db queries.
Is there a way I can access id ?.
From documentation what I understand is that you need to pass id to fetch details and not the other way around.
Any clue or alternative way to solve this issue would be really appreciated.

Do you mean accessing the list of the job like this?
this.schedulerRegistry.getCronJobs().forEach((job) => {
job.stop();
})

Related

Job scheduling in node.js

I want to develop an app which needs to run a scheduled job which writes something to database for every 15 minutes from 9 am to 9 pm
How can i implement this?
Thanks
Look into this package: https://www.npmjs.com/package/node-cron
Here's an example from their docs:
var cron = require('node-cron');
cron.schedule('*/2 * * * *', () => {
console.log('running a task every two minutes');
});
To write to the database the details vary based on what database you're using exactly. For simplicity you can use Express to connect + write to a DB quickly.
Read more here: https://expressjs.com/en/guide/database-integration.html
You can do this.
const CronJob = require("cron").CronJob;
console.log("Before job instantiation");
const job = new CronJob("0 */15 9-21 * * *", function () {
const d = new Date();
console.log("Every 15 minutes between 9-21:", d);
});
console.log("After job instantiation");
job.start();

How can I execute multiple cron jobs at different timings using node-cron in nodejs?

How can I execute this with different timings? Please help on this. Thanks in Advance...
const Cron = require('node-cron');
const Cron2 = require('node-cron');
var TaskOne = Cron.schedule('*/10 * * * *', async() => {
//first job implemented here and its working fine
function1();
});
var TaskTwo = Cron2.schedule('*/11 * * * *', async() => {
// Second job implemented here....
//Why this block is not getting executed???????????????????????
function2();
});
How can I execute this with different timings? TaskTwo is not getting executed. Debugger not goes into TaskTwo. Please help on this. Thanks in Advance...
if node-cron is not the only prefrence for you then you can use https://github.com/agenda/agenda
There's no need to require the same package twice, so you should remove Cron2 on the second line. Thus the line var TaskTwo = Cron2.schedule('*/11 * * * *', async() => { should be changed to:
var TaskTwo = Cron.schedule('*/11 * * * *', async() => {
As for why the second schedule is not working, it might be because you didn't start() the schedule, as shown in https://github.com/node-cron/node-cron#start. So adding the code below at the end of your script might trigger both cron to run:
TaskOne.start();
TaskTwo.start();

Remove job after it is complete in Node Bull is not working

I am using node bull for scheduling. Now for my jobs i pass a cron time to it (which is a specific time and a date). Now since i have provided a strict cron then it must run for only one time or even if it run second time then it must be removed from the queue (i have provided removeOnComplete: true).
But still it doesn't get removed and it runs again and my queue process this job again. So i want to stop this.
My add job function: (data is my job data, timings is my cron timing)
public async addJob(data: any, timings: any, jobId: any) {
console.log('adding job');
console.log(timings);
const job = await this.videoQueue.add(
{data: data},
{
repeat: {
cron: timings,
},
jobId: jobId,
removeOnComplete: true,
},
);
return job;
}
My process function:
this.videoQueue.process(async (job: any) => {
// processing function for my job.
});
I am new node and node bull. Maybe i am making a mistake but i am not able to debug it.
Thanks.
I can suggest you use node-schedule package to schedule with cron time. It's very easy to use actually
const schedule = require('node-schedule');
const job = schedule.scheduleJob('* * * * *', function(){
console.log('Job runned.');
job.cancel();
});

Scheduled Recurring Script - Setting Script to Run Continuously Until Saved Search Results are Null

I have built a script that looks at fields within a saved search to process, when the script processes each line of the saved search . The script has to process a lot of lines of data and I'm running into issue where I get an SSS Usage Limit exceeded message just due to the nature of the amount of information that I'm processing. Therefore I'm wondering if on each run of the script if I can limit the amount of orders processed and then consecutively run the script until there aren't any more records that need to be processed
Previously I have just restricted the number of records that the script processes at a time and then just manually trigger the script until there aren't anymore lines left to process. I see that you can trigger the script to run every 15 minutes or so but would like it to run each day and then run in a 15 minute cadence after that until the saved search has been exhausted. Then the script would be triggered to run again the following day etc for every 15 min until all records are processed. From research don't know if this type of scheduling is possible.
code itself is working the scheduling of it is what I need guidance on
The other alternative (and one that I've used successfully) is to exit the scheduled script whent the usage reaches a certain point, but before you exit, trigger the scheduled script again. I've used this successfully to process thousands of records (such as mass deletions).
/**
* #NApiVersion 2.x
* #NScriptType ScheduledScript
* #NModuleScope SameAccount
*/
define(['N/record', 'N/runtime', 'N/search', 'N/task'],
/**
* #param {record} record
* #param {search} search
*/
function(record, runtime, search, task) {
const governanceCap = 9950;
function getAllResults(s) {
var results = s.run();
var searchResults = [];
var searchid = 0;
do {
var resultslice = results.getRange({start:searchid,end:searchid+1000});
resultslice.forEach(function(slice) {
searchResults.push(slice);
searchid++;
}
);
} while (resultslice.length >=1000);
return searchResults;
}
/**
* Definition of the Scheduled script trigger point.
*
* #param {Object} scriptContext
* #param {string} scriptContext.type - The context in which the script is executed. It is one of the values from the scriptContext.InvocationType enum.
* #Since 2015.2
*/
function execute(scriptContext) {
function rescheduleCurrentScript() {
var scheduledScriptTask = task.create({
taskType: task.TaskType.SCHEDULED_SCRIPT
});
scheduledScriptTask.scriptId = runtime.getCurrentScript().id;
scheduledScriptTask.deploymentId = runtime.getCurrentScript().deploymentId;
return scheduledScriptTask.submit();
}
try {
var script = runtime.getCurrentScript();
// GET YOUR SEARCH HERE
var mySearch = getAllResults(
search.create({
type: "transaction",
filters:
[
["mainline","is","T"],
],
columns:
[
"name",
"tranid",
"type",
search.createColumn({
name:"datecreated",
sort: search.Sort.DESC
}),
]
})
);
var recCount = mySearch.length;
for (each in mySearch) {
try {
record.delete({
type: transSearch[each].getValue({name:'type'}),
id: transSearch[each].id
});
} catch (err) {log.error(err.name,err.message) }
var govPointsUsed = 10000-script.getRemainingUsage();
script.percentComplete = (govPointsUsed/governanceCap*100).toFixed(1);
if (govPointsUsed >= governanceCap) {
var taskId = rescheduleCurrentScript();
log.audit('Rescheduling status: ','Task ID:' + taskId);
return;
}
}
} catch (err) { log.error(err.name,err.message + '; Stack: '+err.stack ) };
}
return {
execute: execute
};
});
Worked like a charm!!
I would encourage you to use a Map/Reduce script. That is the correct script type to use when dealing with a lot of data and can handle governance issues much better.
I had this problem some time ago. The map/reduce script can be the solution if you run 2.0 scripts. In my case, I had 'legacy' scripts in versions 1.X and 2.X. And all of them throw from time to time 'SSS_TIME_LIMIT_EXCEEDED'.
My solution :)
I created a script, kind of 'listener'. I removed link to the script because the rep. is not active anymore
// *add the script listener
// [it can be used for both script versions 1.X and 2.X]
/** you have to calculate the 'process usage' by 1 loop cycle.
use script.getRemainingUsage() */
var recallValue = 200;
var stopValue = 200;
var recallIsRequired = true;// use false to stop the script without recall
var script = setScriptListener(recallValue, stopValue, recallIsRequired);
for (var data in data_contaniner){
if(script.canContinue()){
//run you processing
// !important : mark the data as 'processed'.
//otherwise you will have a lot of duplicates after script recall
}else{
//stop the loop
break;
}
}

Node.js Cron Job Messing with Date Object

I'm trying to schedule several cron jobs to generate serial numbers for different entities within my web app. However I am running into this problem, when I'm looping each table, it says it has something to do with date.js. I'm not doing anything with a date object ? Not at this stage anyway. A couple of guesses is that the cron object is doing a date thing in its code and is referencing date.js. I'm using date.js to get access to things like ISO date.
for (t in config.generatorTables) {
console.log("t = " + config.generatorTables[t] + "\n\n");
var ts3 = azure.createTableService();
var jobSerialNumbers = new cronJob({
//cronTime: '*/' + rndNumber + ' * * * * *',
cronTime: '*/1 * * * * *',
onTick: function () {
//console.log(new Date() + " calling topUpSerialNumbers \n\n");
manageSerialNumbers.topUpSerialNumbers(config.generatorTables[t], function () { });
},
start: false,
timeZone: "America/Los_Angeles"
});
ts3.createTableIfNotExists(config.generatorTables[t], function (error) {
if (error === null) {
var query = azure.TableQuery
.select()
.from(config.generatorTables[t])
.where('PartitionKey eq ?', '0')
ts3.queryEntities(query, function (error, serialNumberEntities) {
if (error === null && serialNumberEntities.length == 0) {
manageSerialNumbers.generateNewNumbers(config.maxNumber, config.serialNumberSize, config.generatorTables[t], function () {
jobSerialNumbers.start();
});
}
else jobSerialNumbers.start();
});
}
});
}
And this is the error message I'm getting when I examine the server.js.logs\0.txt file:
C:\node\w\WebRole1\public\javascripts\date.js:56
onsole.log('isDST'); return this.toString().match(/(E|C|M|P)(S|D)T/)[2] == "D"
^
TypeError: Cannot read property '2' of null
at Date.isDST (C:\node\w\WebRole1\public\javascripts\date.js:56:110)
at Date.getTimezone (C:\node\w\WebRole1\public\javascripts\date.js:56:228)
at Object._getNextDateFrom (C:\node\w\WebRole1\node_modules\cron\lib\cron.js:88:30)
at Object.sendAt (C:\node\w\WebRole1\node_modules\cron\lib\cron.js:51:17)
at Object.getTimeout (C:\node\w\WebRole1\node_modules\cron\lib\cron.js:58:30)
at Object.start (C:\node\w\WebRole1\node_modules\cron\lib\cron.js:279:33)
at C:\node\w\WebRole1\server.js:169:46
at Object.generateNewNumbers (C:\node\w\WebRole1\utils\manageSerialNumbers.js:106:5)
at C:\node\w\WebRole1\server.js:168:45
at C:\node\w\WebRole1\node_modules\azure\lib\services\table\tableservice.js:485:7
I am using this line in my database.js file:
require('../public/javascripts/date');
is that correct that I only have to do this once, because date.js is global? I.e. it has a bunch of prototypes (extensions) for the inbuilt date object.
Within manageSerialNumbers.js I am just doing a callback, their is no code executing as I've commented it all out, but still receiving this error.
Any help or advice would be appreciated.
Ok I've commented out the date.js module and now I'm getting this error:
You specified a Timezone but have not included the time module. Timezone functionality is disabled. Please install the time module to use Timezones in your application.
When I examine the cron.js module it has this statement at the top:
var CronDate = Date;
try {
CronDate = require("time").Date;
} catch(e) {
//no time module...leave CronDate alone. :)
}
So this would conclude then that it does have something to do with the date.js module ?
Anyone see whats wrong.
cheers
I was using date.js for a while, and then realized that the Date object in Node.js/V8 already had ISO support, input and output, and Date.js only added a very specific edge case. What exactly do you need date.js for?
If you do need date.js...
is that correct that I only have to do this once, because date.js is global?
That's true as long as the code is running in the same process. I'm not familiar Node.js on Azure, or the library providing the cronJob method you're using, but perhaps it spawns a new process, which has its own V8 instance, and then you lose the Date object changes? (So require it again in that code.)

Resources