I have a simple node.js parser that has to push data to a remote server during work hours only and sleep for the rest of the time.
Looking at the available modules, schedule and node-cron (https://github.com/ncb000gt/node-cron) seems to do part of my requirement.
I am using the PM2 module to restart the process, when it goes down
Here is what I have so far in coffee script:
runParser = (callback) ->
#...
console.log 'waking up parser...'
parseAll()
return
_jobs = [ {
name: 'Start parser'
cronTime: '00 34 16 * * 1-5'
onTick: runParser
start: true
id: 'parsedbf'
#timeZone: 'Europe/London'
} ]
_cronJobs = {}
schedule = ->
_jobs.map (job) ->
_cronJobs[job.id] = new cronJob(job)
console.log util.format('%s cronjob scheduled at %s on timezone', job.name, job.cronTime)
return
return
run = ->
start = moment('08:30','HH:mm').valueOf()
now = moment().valueOf()
end = moment('18:00','HH:mm').valueOf()
if start < now and now < end
runParser()
else
schedule(console.info 'scheduler started...')
run(console.info 'sync code statrted after a hard reboot...')
my question, how do i change the script so that at 18:30 the parser is just idle?
should i use schedule.js (http://bunkat.github.io/schedule/index.html) how do i modify the code for this?
any advice much appreciated
Is there any reason you can't just run this in cron? You have the question tagged for cron which refers to the unix utility, it was made to do this sort of thing. You could use a combination of cron and forever: one call starts it in the am and another stops the script in the evening but it runs continuously otherwise.
Related
I want to execute a piece code each Sunday 23:59 (11 pm) (basically at the end of each week). However, it should only be fired once per week.
A setInterval() function won't cut it here, as the app might be restarted meanwhile.
If this will help anyhow, I had this basic idea:
Set an interval (with setInterval) for every 5-10 seconds and check if it's Sunday and hour 23 (11 pm). However, this solution will be inconsistent and may fire more than once a week. I need a more bullet-proof solution to this.
You can use any cron module (like https://www.npmjs.com/package/cron) and set job for 59 23 * * 0 (ranges)
const { CronJob } = require('cron');
const job = new CronJob('59 23 * * 0', mySundayFunc);
job.start();
How about calculating the remaining time on start, like this code
const WEEK_IN_MS = 604800000;
const ONE_HOUR_IN_MS = 3600000;
const FOUR_DAYS_IN_MS = 4 * WEEK_IN_MS / 7;
function nextInterval() {
return WEEK_IN_MS - ((Date.now() + FOUR_DAYS_IN_MS) % WEEK_IN_MS) - ONE_HOUR_IN_MS;
}
const interval = nextInterval();
console.log(`run after ${interval} ms`);
setTimeout(
() => console.log('Do it!!!'),
interval
)
I am using the scheduled script which will create the custom records based on criteria. every time when the schedule script runs it should create approx. 100,000 records but the script is timing out after creating 5000 or 10000 records. I am using the below script to prevent the script execution usage limit but even with this also the script is not working. can any one please suggest some thing or provide any information. any suggestions are welcome and highly appreciated.
In my for loop iam using the below script. with this below script included the scheduled script is able to create up to 5000 or 10000 records only.
if (nlapiGetContext().getRemainingUsage() <= 0 && (i+1) < results.length )
{
var stateMain = nlapiYieldScript();
}
If you are going to reschedule using the nlapiYieldScript mechanism, then you also need to use nlapiSetRecoveryPoint at the point where you wish the script to resume. See the Help documentation for each of these methods, as well as the page titled Setting Recovery Points in Scheduled Scripts
Be aware that nlapiSetRecoveryPoint uses 100 governance units, so you will need to account for this in your getRemainingUsage check.
#rajesh, you are only checking the remaining usage. Also do check for execution time limit, which is 1 hour for any scheduled script. Something like below snippet-
var checkIfYieldOrContinue = function(startTime) {
var endTime = new Date().getTime();
var timeElapsed = (endTime * 0.001) - (startTime * 0.001);
if (nlapiGetContext().getRemainingUsage() < 3000 ||
timeElapsed > 3500) { //3500 secs
nlapiLogExecution('AUDIT', 'Remaining Usage: ' + nlapiGetContext().getRemainingUsage() + '. Time elapsed: ' + timeElapsed);
startTime = new Date().getTime();
var yieldStatus = nlapiYieldScript();
nlapiLogExecution('AUDIT', 'script yielded.' + yieldStatus.status);
nlapiLogExecution('AUDIT', 'script yielded reason.' + yieldStatus.reason);
nlapiLogExecution('AUDIT', 'script yielded information.' + yieldStatus.information);
}
};
Inside your for loop, you can call this method like-
var startTime = new Date();
if ((i+1) < results.length ) {
//do your operations here and then...
checkIfYieldOrContinue(startTime);
}
I have a script that lets you process an array like a forEach. The script checks each iteration and calculates the maximum usage and yields when there is not enough usage left to cover the max.
Head over to https://github.com/BKnights/KotN-Netsuite and download simpleBatch.js
I want to use a own errorhandling on quartz jobs. Each job has a different waiting time, when an exception occurs. For example, a job runs every 30 seconds, but when an exception occurs, the job should wait for 5 minutes.
I tried this approach, but it doesn't work:
SchedulerFactory sf = new StdSchedulerFactory()
Scheduler sched = sf.getScheduler()
def name = "jobname"
Trigger trigger = sched.getTrigger(new TriggerKey("trigger_" + name))
def currentDate = new Date()
use (TimeCategory) {
currentDate = currentDate + 300.seconds
}
trigger.nextFireTime = currentDate
The job runs in 30 seconds again.
What am I doing wrong?
I may be wrong but are you sure you can schedule a job by simply setting the nextFireTime property?
I guess you have to use http://quartz-scheduler.org/api/2.2.0/org/quartz/Scheduler.html#rescheduleJob(org.quartz.TriggerKey, org.quartz.Trigger) do reschedule a job.
e.g.
SchedulerFactory sf = new StdSchedulerFactory()
Scheduler sched = sf.getScheduler()
def name = "jobname"
Trigger trigger = sched.getTrigger(new TriggerKey("trigger_" + name))
trigger.repeatInterval = 30000
sched.rescheduleJob(trigger.name, trigger.group, trigger)
That would run the job in 5 minutes and then you'd have to reschedule it to run in 30 seconds.
I need to run code in Node.js every 24 hours. I came across a function called setTimeout. Below is my code snippet
var et = require('elementtree');
var XML = et.XML;
var ElementTree = et.ElementTree;
var element = et.Element;
var subElement = et.SubElement;
var data='<?xml version="1.0"?><entries><entry><TenantId>12345</TenantId><ServiceName>MaaS</ServiceName><ResourceID>enAAAA</ResourceID><UsageID>550e8400-e29b-41d4-a716-446655440000</UsageID><EventType>create</EventType><category term="monitoring.entity.create"/><DataCenter>global</DataCenter><Region>global</Region><StartTime>Sun Apr 29 2012 16:37:32 GMT-0700 (PDT)</StartTime><ResourceName>entity</ResourceName></entry><entry><TenantId>44445</TenantId><ServiceName>MaaS</ServiceName><ResourceID>enAAAA</ResourceID><UsageID>550e8400-e29b-41d4-a716-fffffffff000</UsageID><EventType>update</EventType><category term="monitoring.entity.update"/><DataCenter>global</DataCenter><Region>global</Region><StartTime>Sun Apr 29 2012 16:40:32 GMT-0700 (PDT)</StartTime><ResourceName>entity</ResourceName></entry></entries>'
etree = et.parse(data);
var t = process.hrtime();
// [ 1800216, 927643717 ]
setTimeout(function () {
t = process.hrtime(t);
// [ 1, 6962306 ]
console.log(etree.findall('./entry/TenantId').length); // 2
console.log('benchmark took %d seconds and %d nanoseconds', t[0], t[1]);
//benchmark took 1 seconds and 6962306 nanoseconds
},1000);
I want to run the above code once per hour and parse the data. For my reference I had used one second as the timer value. Any idea how to proceed will be much helpful.
There are basically three ways to go
setInterval()
The setTimeout(f, n) function waits n milliseconds and calls function f.
The setInterval(f, n) function calls f every n milliseconds.
setInterval(function(){
console.log('test');
}, 60 * 60 * 1000);
This prints test every hour. You could just throw your code (except the require statements) into a setInterval(). However, that seems kind of ugly to me. I'd rather go with:
Scheduled Tasks
Most operating systems have a way of sheduling tasks. On Windows this is called "Scheduled Tasks" on Linux look for cron.
Use a libary As I realized while answering, one could even see this as a duplicate of that question.
I'm thinking about making a Hubot clock-based notifier (think "It's 5, time to go home!" but less annoying and for a different reason). What's the best way to go about doing something like this in a Hubot script?
[edit] Here's an example using node-cron:
TIMEZONE = "America/New_York"
QUITTING_TIME = '0 0 17 * * 2-6' # M-F 5pm
ROOM = "Dev"
cronJob = require('cron').CronJob
module.exports = (robot) ->
gohome = new cronJob QUITTING_TIME,
->
robot.messageRoom ROOM, "It's 5! Go home!"
null
true
TIMEZONE
dependencies:
"cron": "0.3.3",
"time": "0.8.2"
I would use node-cron. It's pretty flexible and fits your use case well.
https://github.com/ncb000gt/node-cron
I just stumbled upon hubot-cron.
This lets you schedule messages in hubot, but unfortunately doesn't persist jobs through restarts.