Here's our scenario:
We are using node w/ express for our web app and we need to create a background process that continuously checks the created date on multiple posts and when they expire. These expired dates are set by the user so the posts expire at different rates. When the date expires, our app should be triggering specific events.
We are considering using a "setInterval" but wasn't sure if this is the best long-term solution.
Is there a solution to have node continuously check whether or not a date has been expired? Upon expiring, the posts must trigger specific functions.
There are two ways to do this:
1) use moment lib like this:
var date = moment("2013-03-24")
var now = moment();
if (now > date) {
// date is past
} else {
// date is future
}
2) use node-schedule like this:
var schedule = require('node-schedule');
var futureDate = new Date(new Date().getTime() + 60 * 60 * 24 * 1000); // This is 24 hours from *now*
var j = schedule.scheduleJob(futureDate, function(){
console.log('Do your work here.');
});
Im not sure about your code but if u can catch the event when the users post, the easy way would be
setTimeout(whateverYouHaveTodo, expireTimeInMilliseconds);
each time an event is triggered.
And if you need to cancel the timeouts in the future, what i do personally is put the timeouts in a json object with the key as a unique id which you could identify the event specifically
Related
I would like to have a countdown timer always show a countdown for every new user. Basically, if I close the webpage, and reopen it, the timer should still be running. I'm thinking of using the JS variable code functions to define a new client's timezone together with an if statement comment and make it a repeat loop?
Basically, I would want to run a timer on the server side, not the client side.
Has anyone done this before?
Sounds something that you could try to solve with browsers localStorage. If your only requirement is to keep saved time available after you close tab/browser and come back to your page, this is a good fit for you.
Here's a small Codesandbox example code of how to conditionally check and save to localStorage and then start counter based on that value.
https://codesandbox.io/s/4xw97q02m0
EDIT: same code pasted to a post
function setCurrentTime(){
let localStore = window.localStorage.getItem("myTime") // Check if already exists
if(localStore) return localStore
const time = Date.now(); // get current time stamp
window.localStorage.setItem("myTime", time) // Save to localStorage
return time
}
function startCount(){
const time = setCurrentTime()
const elem = document.getElementById("app")
setInterval(() => {
elem.innerHTML = `seconds since time saved:
${Math.floor((Date.now() - time) / 1000)}
`
}, 1000)
}
startCount()
<div id="app"></div>
I want to keep track of how many seconds a user spend on my project website on all of his pages and for doing this I want to use JavaScript session cookies.
This is because I will host it using Github Pages where I have no access to PHP and also because I want to try working with JS cookies (It's the first time I am doing this).
To count the seconds I am using the followings:
var time_spent = 0;
setInterval(function(){
++time_spent;
$('#counter_container span').html(time_spent);
}, 1000);
The above code works where the counter is but as expected is reseting every time I change the page.
I've tried using a js-cookie library (https://github.com/js-cookie/js-cookie) in the following manner:
Cookies.set('time_spent', time_spent);
var counted_time = Cookies.get('time_spent');
console.log(counted_time);
But the counted_time variable is always 'undefined' whatever I've tried.
I would really apreciate any guidance I can get in order to solve this little issue.
I wouldn't use a timer for this. Instead try setting a timestamp when the user enters the page, and then onbeforeunload get the duration and add it to the value stored in the cookie. Something like this:
var load = new Date();
window.onbeforeunload = function() {
var leave = new Date();
var duration = leave.getTime() - load.getTime() / 1000;
var counted_time = parseFloat(Cookies.get('time_spent')) || 0;
Cookies.set('time_spent', counted_time + duration);
}
Working example
In my app, I use this code to listen only to the children added after the current time:
var start = new Date().getTime();
firebase.database().ref(path).orderByChild('created').startAt(start).on('child_added', function(value){
console.log(value.val());
});
In the browser, this method works well. I see the child only if I start to add it after the current time.
In the smartphone, this method doesn't work. It works only if I start to add a children after a certain amount of seconds. I think that this happens because the current time of the smartphone is different with the current time of the server.
Is there any way to fix this without having to take the last element?
If the clock on your phone is off, this will not work reliably.
Firebase detects the offset of the local clock to the server time and exposes this in a value .info/serverTimeOffset. You can use this to correct for the clock skew as explained in the documentation on clock skew:
var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", function(snap) {
var offset = snap.val();
var estimatedServerTimeMs = new Date().getTime() + offset;
});
Read the linked documentation for a full explanation.
I would like to allow my users set a schedule when they would like a particular action to occur. I use a node server on azure. I am currently looking at node-schedule and would be making use of it. What I am contemplating is running a master schedule every hour that checks the database for user specified schedules and this schedule sets a new schedule based on the schedules from users. But I don't know if this is a good practice, plus I'm concerned about the server load.
You can use node's cron for that, and accommodate in different ways.
The pseudocode below gives a general idea.
var CronJob = require('cron').CronJob;
new CronJob('0 0 * * * *', function () { // every hour
// check schedules planned for the future, stored as ISODate
DB.getUserSchedule({jobdate:{$gte:Date.now()},
function(userSchedules) {
userSchedules.forEach(sched) {
// convert the date back to a string parsed by cron
var d=extractDayHourMin(sched)
var jobtime = d[4] +' '+d[3]+' '+d[2]+' '+d[1]+' '+d[0]
// setup a new job
var job=new CronJob(jobtime, function() {
performUserJob()
job.stop(); // fires only once
DB.removeUserSchedule(userSchedule);
})});
see https://github.com/ncb000gt/node-cron
However, this is possibly not the best solution : this does creates as much process as schedule, so yes, it would consume more resources than required. Instead of scheduling the schedulers, depending on the granularity of the possible calendar (hour, 1/2 hour, 1/4h), you could also query the db every hour (or 30 or 15mn) to retrieve every date that met, and trigger the appropriate function.
Search Quartz schedule.
My project using that to set the time to send email.
I was creating a countdown timer using javascript; I can use jQuery. I want the global time not the PC time.
How could I get the global time using javascript or the jQuery?
Use a time API like: http://www.timeapi.org/
<script type="text/javascript">
function myCallback(json) {
alert(new Date(json.dateString));
}
</script>
<script type="text/javascript" src="http://timeapi.org/utc/now.json?callback=myCallback"></script>
You can use the UTC methods from Date object: http://www.w3schools.com/jsref/jsref_obj_date.asp
var utcDate = new Date(json.dateString);
alert(utcDate.getUTCFullYear() + '-' + utcDate.getUTCMonth() + utcDAte.getUTCDate());
Well unless you make a request to some service that publishes like the current time of an atomic clock or something, you'll have to rely on your computers local time. As JS inherently relies on your local system.
The Date object has built-in methods for getting UTC values. Instead of myDate.getHours() use myDate.getUTCHours(), etc.
See the MDN reference for JavaScript date methods.
Using your current API with server time like following:
res.send(new Date());
You can get an approximate clock difference time with following:
// Get current local time before request
const initialLocalTime = new Date().getTime();
// Request server time
const response = await fetch('/api/time');
const data = await response.json();
const serverTime = new Date(data);
// Get current local time after request
const finalLocalTime = new Date().getTime();
// Calculate the request time
const dateDiff = finalLocalTime - initialLocalTime;
// Apply the request time to server time
serverTime.setTime(serverTime.getTime() + dateDiff);
// Calculate the time difference
const diff = serverTime.getTime() - finalLocalTime;
// Return the final difference time
return diff;
And, you can use the diff value in your page:
const now = new Date()
now.setTime(now.getTime() + diff);
console.info('Current time:', now);