i want to include node scheduling code in my sails - cron

i want to include node scheduling code in my sails , but i don't know where i put the code in my sails .
But i tried to put the code in my config/bootstrap.js .but it doesn't run . code is
sails.on('lifted', function() {
var schedule = require('node-schedule');
var j = schedule.scheduleJob({hour: 0, minute: 1, dayOfWeek: 0}, function(){
console.log('Time for tea!');
});
});
I want to know , where i put this code. Main conditions is , that file execute every time when my sails server lift.

Sorry if it doesn't format the code since I am on my tablet. This was surprisingly easy. I used node-cron and put the following code in my services folder as a file called Cron.js
I do not believe I had to place any code anywhere else to start the job.
/*
https://github.com/ncb000gt/node-cron
Read up on cron patterns here. http://crontab.org/
When specifying your cron values you'll need to make sure that your values fall within the ranges. For instance, some cron's use a 0-7 range for the day of week where both 0 and 7 represent Sunday. We do not.
Seconds: 0-59
Minutes: 0-59
Hours: 0-23
Day of Month: 1-31
Months: 0-11
Day of Week: 0-6
How to check if a cron pattern is valid:
try {
new CronJob('invalid cron pattern', function() {
console.log('this should not be printed');
})
} catch(ex) {
console.log("cron pattern not valid");
}
constructor(cronTime, onTick, onComplete, start, timezone, context) - Of note, the first parameter here can be a JSON object that has the below names and associated types (see examples above).
cronTime - [REQUIRED] - The time to fire off your job. This can be in the form of cron syntax or a JS Date object.
onTick - [REQUIRED] - The function to fire at the specified time.
onComplete - [OPTIONAL] - A function that will fire when the job is complete, when it is stopped.
start - [OPTIONAL] - Specifies whether to start the job just before exiting the constructor. By default this is set to false. If left at default you will need to call job.start() in order to start the job (assuming job is the variable you set the cronjob to).
timeZone - [OPTIONAL] - Specify the timezone for the execution. This will modify the actual time relative to your timezone.
context - [OPTIONAL] - The context within which to execute the onTick method. This defaults to the cronjob itself allowing you to call this.stop(). However, if you change this you'll have access to the functions and values within your context object.
start - Runs your job.
stop - Stops your job.
*/
var CronJob = require('cron').CronJob;
var job = new CronJob({
cronTime: '00 30 11 * * 1-5',
onTick: function() {
// Runs every weekday (Monday through Friday)
// at 11:30:00 AM. It does not run on Saturday
// or Sunday.
},
start: false,
timeZone: "America/Los_Angeles"
});
job.start()
;

As you rightly said config/bootstrap.js is one place where you can have your Job schedulers,
The below cron will execute at 00 hrs 00 mins 00 secs daily
From the left
The first 00 is seconds can hold values (00-59)
The second 00 is minutes can hold values (00-59)
The third 00 is hours can hold values (00-23)
The fourth position * is Day can hold values (00-30)
The fifth position * is Month can hold values (00-11)
The sixth position * is the Day of Week can hold values (0-6)
module.exports.bootstrap = function (cb) {
try {
var CronJob = require('cron').CronJob;
new CronJob('00 00 00 * * *', function() {
sails.controllers.controllerName.functionName(sails.request, sails.response, sails.next, function(err,data){
console.log(err,"err");
});
}, null, true);
}
catch(ex) {
console.log("cron pattern not valid");
}
cb();
};
Note: The function which you are using should not have any res.json or res.something

Related

How can i run some code at an exact timestamp?

I have a REST API in a backend with an array of objects with a timestamp (time when something happens in-game) and a value.
{"timestamp":1623320102097,"crops":[0,5,9]}
How can i do run something when time is equals to that timestamp ?
I presume that timestamps are in msec. Probably this should do the trick:
let diffMsec = obj.timestamp - new Date().getTime();
if (diffMsec > 0) {
setTimeout(function() {
/* do your stuff */
}, diffMsec);
}
Keep in mind though, that it is not guaranteed that timeout will be invoked at the exact time.

Scan DynamoDB attribute which is a cron string and filter based on current time

I have a DynamoDB table with the following items
{
"jobId":<job1>,
"cron" : "* 5 * * *"
},
{
"jobId":<job2>,
"cron" : "* 8 * * *"
}
I need to scan items who next execution time based on cron string is within the next 5 minutes, based on current time.
Is there a way I can convert the cron to a valid next execution time while scanning?
I am using node.js in AWS Lambda and cron-parser npm library to extract next_execution time from cron string.
Note that scanning the full table will slow down over time. You may want to consider some other data store or structure to store this data.
That said something like this could work:
const results = await client.scan({ TableName: 'tableName' }).promise();
const cronItems = results.Items;
const intervals = cronItems.map((item) => {
return cronParser.parseExpression(item.cron);
});
const now = new Date();
const fiveMinMillis = 300 * 1000;
const within5Mins = intervals.filter((interval) => {
const timeUntil = interval.next().valueOf() - now.valueOf();
return timeUntil < fiveMinMillis;
});
Note you will actually need to call scan(...) iteratively until the response does not include a LastEvaluatedKey attribute. See here for details.

Play each track at specific time position from a playlist

I want users to be able, to continue a track from where they paused or stopped it last time. I save a users key into a cookie, and store the chosen tracks and elapsed times into db. Then before a activated song is going to play the current time should be set at the retrieven elapsed time:
ie. User lately ilstened to these two songs
song1.mp3n, stopped at 2 sec
song3.mp3 stopped at 100 sec
I found some information at.
Play song at specific time position from a playlist
I came up with the following code:
$jplay= <<<EOD
var jp = $('#jquery_jplayer_1pl');
jp.on($.jPlayer.event.setmedia, function(e){
// For first track (0) - 2 sec, second track (1) - 3 sec, etc.
//var time = myPlaylist.current + {$time_elapsed};
var time = {$time_elapsed};
// Jump to desired time
setTimeout(function(){
jp.jPlayer( "play", time);
}, 100);
});
EOD;
But this only works with single player version, unless the last track, the user listended to, could be activated or played automatically. Otherwise every song strts at the same time position.
Therefore I think I could use "myPlaylist.play(0);" or "myPlaylist.play(2);", but I cannot find out how.
To be more precise, I want to start several tracks at different elapsed time positions, when they are activated.
Thanks.
To make this work for the playlist player version of jplayer, after days I found out the following solution myself, based on jquery and ajax.
$("#jquery_jplayer_1pl").bind($.jPlayer.event.setmedia, function(event) {
$.ajax({
type: "GET",
url: 'media-progress-ajax-funcs1.php',
data: {
guid: myPlaylist.playlist[myPlaylist.current].mp3,
bkmk_key: '<?php echo $bkmk_key; ?>',
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
playtrack(response['timeElapsed']);
}
});
});
function playtrack(elapsed) {
if (elapsed) {
var jp = $('#jquery_jplayer_1pl');
var time = parseInt(elapsed);
// Jump to desired time
setTimeout(function(){
jp.jPlayer( "pause", time);
}, 100);
}
}
Explanation:
data: {
guid: myPlaylist.playlist[myPlaylist.current].mp3,
bkmk_key: '<?php echo $bkmk_key; ?>',
}
The variable bkmk_key is derived from a cookie and unique for a cetain user. The ajax function script 'media-progress-ajax-funcs1.php' is searching for the userkey and corresponding media filename (guid) the user has paused after a certain time (elapsed time from event.jPlayer.status.currentTime) and returns the elapsed time value if the media is set (event:setmedia). It will start playing by clicking play from the latest position, so the user has not to search for it.
I do not mention howto get the elapsed time, after the player is paused, and store it into the database. If you are interested in this part of my code you will have to ask.
I hope that someone finds this helpful.

How do I make an offer redeemable everyday(from midnight to midnight) vs every 24 hours?

I am trying to understand how to modify my 'timeDiff' so that I am able to redeem based on if it is a new day vs whether it has been 24 hours. Any advice?
let timeDiff = prevRedemp ? Math.floor((new Date - new Date(prevRedemp.createdAt)) / 1000 / 60 / 60) : undefined;
// daily use
} else if (discFreq === 1) {
if (timeDiff >= 24 || prevRedemp === undefined) {
return this.models.Redemption.create({
UserUuid: userUuid,
DiscountId: discountId,
BusinessId: disc.dataValues.BusinessId,
locationId: locationId || null
}).then(redeemed => {
return this.models.BusinessRating.findOne({
where: {
UserUuid: userUuid,
BusinessId: disc.dataValues.BusinessId
}
}).then(rating => {
if (rating) {
return redeemed;
} else {
return this.models.Notification.create({
UserUuid: userUuid,
notifyDate: moment().format(),
notifyType: 'redemption',
RedemptionId: redeemed.id
}).then(() => redeemed);
}
});
})
} else {
return `Discount cannot be redeemed again for ${24 - timeDiff} hours`;
}
It's not entirely clear to me what your end problem is, but you can create a Date object for the next midnight boundary in the current server time zone like this:
let midnt = new Date();
midnt.setHours(24); // set hours to the next midnight boundary
midnt.setMinutes(0); // clear minutes, seconds, milliseconds to zero
midnt.setSeconds(0);
midnt.setMilliseconds(0);
console.log(midnt.toString());
This gives you a midnight reference that you can calculate time differences from. For example, if you want something to expire at the next stroke of midnight, you can either set the expiration absolute time for that or if you are working with time differences from now, you can subtract that time in the future from the current time to get the time difference between now and midnight.
If you want the midnight after the next one (so you always get at least 24 hours), then you can just increase the day of the month by one or add 24 * 60 * 60 * 1000 milliseconds to the ordinal value of the midnight date or you can just increase the day of the month by one to move it forward a day.

mongo db, compass - creating ttl index

I need to delete documents in collection after 7 days from creation, unless "confirmed" value is equal true. I am creating index like on screenshot but it does not work. I am using Node.js for server if it matter.
You can use rule npm package https://www.npmjs.com/package/node-rules to do this.
you can define a rule and if the rule is executed then the consequeces will be deleting the document. if the rule is to calculate the days count from the creation date of the file
var RuleEngine = require("node-rules");
/* Creating Rule Engine instance */
var R = new RuleEngine();
/* Add a rule */
var rule = {
"condition": (R) => {
console.log(this);
// check if a document creation date and current date , dates >= 7
// and check for other condition
},
"consequence": (R) => {
// delete the document
// if above condition met
}
};
you need cron job to achieve this
try something like this (I'm using node-cron but you can use any cron job lib you want)
import cron from 'node-cron'
import Collection from 'models/YourCollection'
cron.schedule('0 12 * * * *', () => { // execute everyday at 12:00
const lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() -7);
Collection.deleteMany({'created_at': {'$lte': lastWeek}}) // created more than 7 days
});

Resources