NodeJS - Schedule a very simple task to run at a certain datetime - node.js

I am implementing a booking system, and I need to record the concept of the time between the job being accepted and the job starting, and then the duration of the job. I need to move from 'State A' to 'State B' when the start time of the job is reached, and then from 'State B' to 'State C' once the end time of the job has been reached.
I know I could implement this using a queue system like Bull or Bee-Queue, but it seems wrong, as I only need to change the 'State' of my job, not perform any background processing.
How can I simply say "At 3pm, change this Task to 'State B', and at 5pm, change this Task to 'State C'".
Could I poll my DB every minute? Is this the 'correct' approach?

How about using node-cron module? You can use node-cron to schedule jobs based on time, frequency etc. see the official link for more examples
https://www.npmjs.com/package/node-cron
I pasted one for reference
var cron = require('node-cron');
cron.schedule('* * * * *', function(){
console.log('running a task every minute');
});

An approach that doesn't involve scheduling would be to have the value of your state property calculated at request time.
Instead of updating the value of state at exactly 3pm, you check the current time when someone requests the booking resource. If it's >3pm and <5pm return the state as 'State B'. If its >5pm, return state as 'State C'.

You can use setTimeout(function, timeout) to schedule task at certain period of time.
var now = new Date(); //creates date object at current time
var date = new Date(...); //create first state-changing time
//Execute task after (date - now) milliseconds
setTimeout(function(){
//execute tasks
}, date - now);
Now you can do setTimeout() inside setTimeout() with the help of loops to complete your task!

Related

Electron.JS is being very CPU intensive, I can't tell what's wrong with my code

I have written an application to show GPU/CPU/RAM loads in electron.js! It was all ok until I started implementing gauges to graphically display temperatures. This section is shown below, I have also included a screenshot of task manager showing hundreds of command and powershell windows!
function getGPUtempHome(){
let stinker = si.graphics();
stinker.then(function(tempGPU){
GPUtempHome = tempGPU.controllers[0].temperatureGpu;
console.log(GPUtempHome);
document.getElementById("GPUtemps").innerHTML = GPUtempHome+'°';
document.documentElement.style.setProperty('--GPUTEMP', GPUtempHome*1.8 + 'deg');
});
setInterval( function() {getGPUtempHome();}, 5000 );
}
function getRAMhome(){
let stinker3 = si.mem();
stinker3.then(function(RAM){
RAMUSAGE = Math.round(((RAM.used/RAM.total)*100));
console.log(RAMUSAGE);
document.getElementById("RAMloads").innerHTML = RAMUSAGE+'%';
document.documentElement.style.setProperty('--RAMLOAD', RAMUSAGE*1.8 + 'deg');
});
setInterval( function() {getRAMhome();}, 5000 );
}
The code above fetches RAM load or GPU temperature every 5 seconds, it then updates a HTML/CSS gauge.
If writing a program like this is unviable in electron.js are there any other better options out there, I am open to playing around with new languages/libraries.
Remember, setInterval() sets a recurring timer, so your code is basically saying "Every five seconds create another timer for every five seconds." After ten seconds you will have 2 timers. After 20 you now have 8. After 60 seconds you have 4,096 of them. Every 5 seconds the number of timers doubles.
That sounds like a problem, doesn't it?
What you want to do is set one timer, once, per function:
function getRAMhome(){
let stinker3 = si.mem();
stinker3.then(function(RAM){
RAMUSAGE = Math.round(((RAM.used/RAM.total)*100));
console.log(RAMUSAGE);
document.getElementById("RAMloads").innerHTML = RAMUSAGE+'%';
document.documentElement.style.setProperty('--RAMLOAD', RAMUSAGE*1.8 + 'deg');
});
}
// Set timer outside of the function
setInterval(getRAMhome, 5000);
It's a common problem to confuse setInterval() which sets a repeating timer with setTimeout() which sets a one-shot timer that needs to be re-engaged. You're treating the former like the latter, with disastrous consequences.

Dynamic cron parameters _ Node Js

I have a script that send an email to specific customer but what I'm trying to do is to fire that email in a given time and date .. so the solution is to use cron module like below and changing the parameters with what I want
cron.schedule("* * * * * " , function(){
}
the problem that I want to modify those parameters with varibales which contains a result for a specific calculation! like this below
const X = 234;// this values will change everyday automatically
cron.schedule("X * * * * " , function(){
}
so is it possible to do something like that or is there a better solution that allows me to modify cron parameters
the solution that I tried but nothing is working is below :
const x = 40;// 40 seconds
cron.schedule(`${x} * * * *`, function(){
}
Best Regards,
Many Thanks to num8er ,
the only solution for my problem is
Simply save to table jobs the stuff need to do and put cron script to run every minute which will check jobs table and will run what is scheduled by time. Example table: jobs [id, runAt, method, arguments, done], cron will run and will take jobs which is not done and runAtis less than now, will run method and pass arguments to it and after finishing it will set done=true
that's enough simple to achieve: 1 insert to table, 1 method that will run by cron and get jobs from table and execute

Schedule Repeatable Jobs using bull.js By providing time in repeat rules

I'm currently using bull js to create an api that schedules a job according to inputted time. currently I'm able to do this using crone expression if the time input is in the format of 'YYYY-MM-DD HH:mm". The only problem is that if I want to schedule a job that will run daily I have to write some logic to get time from the inputed time. My question is whether I can specify the repeat rules using a date input as it is done in node-schedule. in short, am looking for the equivalent of the following node-schedule implementation in bull.
var date = new Date(2012, 11, 21, 5, 30, 0);
var j = schedule.scheduleJob(date, function(y){
console.log(y);
}.bind(null,x));```
Based on the documentation, repeating tasks/jobs are handled using cron syntax:
paymentsQueue.process(function(job) {
// Check payments
});
// Repeat payment job once every day at 3:15 (am)
paymentsQueue.add(paymentsData, { repeat: { cron: "15 3 * * *" } });
Use this cron expression validator to verify your logic is correct.

Socket.io countdown synchronously? [duplicate]

This question already has answers here:
Sync JS time between multiple devices
(5 answers)
Closed 5 years ago.
On my server I call two emits at the same time, which looks like this.
if (songs.length > 0) {
socket.emit('data loaded', songs);
socket.broadcast.to(opponent).emit('data loaded', songs);
}
The one is for opponent and the other for himself.
Once the data is loaded a countdown should appear for both players on my android app. For me it is important that they see the same number at the same time on their screen. To be precise it should run synchronized. How can I do this?
As far as js timers are concerned the will be a small amount of difference. We can reduce the difference in time with reduce of latency time, with the difference between the request and response time from the server.
function syncTime() {
console.log("syncing time")
var currentTime = (new Date).getTime();
res.open('HEAD', document.location, false);
res.onreadystatechange = function()
{
var latency = (new Date).getTime() - currentTime;
var timestring = res.getResponseHeader("DATE");
systemtime = new Date(timestring);
systemtime.setMilliseconds(systemtime.getMilliseconds() + (latency / 2))
};
res.send(null);
}
Elapsed time between sending the request and getting back the response need to be calculated, divide that value by 2. That gives you a rough value of latency. If you add that to the time value from the server, you'll be closer to the true server time (The difference will be in microseconds)
Reference: http://ejohn.org/blog/accuracy-of-javascript-time/
Hope this helps.
I have made an application and I had the same problem. In That case I solved the problem leaving the time control to the server. The server send to the client and the client increases the time. Maybe in your case you could have problem with connection. If the problem exists you can leave clients to increase time by yourself and some times send a tick with correct time for sync.
I could give you something like bellow but I am not tested.
This solution have these steps:
Synchronize timers for client and server. all users have the same difference with server timer.
For the desired response/request get clients time and find the differences with server time.
Consider the smallest as first countdown which will be started.
For each response(socket) subtract the difference from smallest and let the client counter starts after waiting as much as this time.
The client that gets 0 in response data will start immediately.
and the main problem that you may will have is broadcast method which you can't use if you think this solution will be helpful.
This is a post may will help you.
Add time into emit message.
Let's say that songs is an object with {"time" : timeString, "songs" : songsList}.
If we consider devices time is correct You can calculate the time needed for information to travel and then just use server timer as a main calculator.
The client would get the time when countdown should start:
var start = false;
var startTime = 0;
var myTime = new Date().getMilliseconds();
var delay = 1000 - myTime;
setTimeout(function(){
intervalID = setInterval(function(){
myTime = new Date().getTime();
//console.log(myTime); to check if there is round number of milliseconds
if (startTime <= myTime && start = true) {startCountdown();}
}, 100); //put 1000 to check every second if second is round
//or put 100 or 200 is second is not round
}, delay);
socket.on('data loaded', data){
startTime = data.time;
start = true;
}
function startCountdown(){
//your time countdown
}
And that works fine when 2 clients are from same time region, therefore You will need "time converter" to check if time is good due to time difference if You strictly need same numbers.
After the countdown has ended You should clearInterval(intervalID);

Hangfire Cron Expression failing

I have a task scheduled like this:
RecurringJob.AddOrUpdate("Process inbound external messages", () => ProcessInboundExternalMessages(), Cron.Minutely);
It works.
But I need one to fire ever midnight.
So I tried to create a cron expression:
private const string CronDailyAtMidnight = "0 0 * * *";
And then assign that to my task.
RecurringJob.AddOrUpdate("Deactivate user role allocation on expiry", () => DeactivateUserRoleAllocationOnExpiry(), CronDailyAtMidnight);
However, it never fires. Can anyone see an issue?
The issue was - it uses UTC date. Fixed.

Resources