I am trying to schedule a task after 10 minutes in node.js heroku. I have created a file worker.js in program main directory. In worker.js I have just called the controller function that I want to schedule like this :
const reports = require('./app/controllers/reports');
reports.sendEmail();
sendEmail function use to send emails. in Heroku scheduler I have add worker.js as :
but my scheduler is not working. What I am missing in my configuration?
Edit your Heroku Scheduler dashboard, and type node worker.js for the command to be executed.
Related
I have set up an Angular project and it is consuming APIs from the NodeJS app.
Angular dashboards have some reports/charts, I will configure a schedule somewhere in DB.
I want to add scheduling functionality so that I will get an automated email containing a graph/chart as an email body.
Can anyone guide me here!
Your scheduling will have to happen out of the NodeJS app since that can be always 'alive' The Angular project is only doing things when you've loaded it in your browser and cannot process that scheduled emails when you don't have it open (unless you were to make it a PWA perhaps, but then still it would be rather convoluted to do it out of Angular).
Do all the processing on the server, including generating and rendering the charts to an email message that you send over SMTP or through a service like Mailgun or Sendgrid.
You can use node-schedule package from npm node-schedule, it will help you to schedule cron jobs whenever you want to send email.
const schedule = require('node-schedule')
const job = schedule.scheduleJob('21 * * * *', function(){
console.log('Send my email.')
})
This will excute this cron at exactly 21min of any hour.
You can go through the npm package for more scheduling details.
I have configured this cronjobe using node-cron in my node.js project
const cron = require('node-cron');
cron.schedule('0 0 * * *', () => {
console.log("CRON: Running");
// Do someting
});
and deployed project to Google APP engine, this cron normally runs on my local during testing at 24:00 no issue, but on Google APP engine it is not ...
Project itself normally deployed to server and running no issues (accessible through web) but cornjobe seems did not triggered at 24:00 by app engine server, i'm trying to understand why ?? Seems server was off at moment when no one is using it, or ??
This is because the App Engine instance is not necearily running at the time of the execution. (this happends more with Standard as it can scale down to 0)
Therefore a workaround for have Cronjobs in app engine is to have the schedule of this jobs managed by something else, in this case Google Cloud Scheduler which basically is a scheduler for tasks in app engine.
In This Guide You can see how to create cron job with the cloud Scheduler by the cloud console.
I want to deploy a NodeJS server on a worker-only dyno on heroku. I've tried several approaches but I always get the error:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
My server does not need to serve files or an API. What is the correct way to deploy to Heroku? Specifically, what is the correct way to deploy only a firebase-queue implementation to Heroku?
My server is dedicated to process work from a queue. It monitors a Firebase location and reacts on changes. Specifically, its a firebase-queue implementation, almost an exact copy of my-queue-worker.js as given in the guide
var Queue = require('firebase-queue');
var firebase = require('firebase');
firebase.initializeApp({
serviceAccount: '{projectId: 'xx', clientEmail: 'yy', privateKey: 'zz'}',
databaseURL: '<your-database-url>'
});
var ref = firebase.database().ref('queue');
var queue = new Queue(ref, function(data, progress, resolve, reject) {
// Read and process task data
console.log(data);
// Do some work
progress(50);
// Finish the task asynchronously
setTimeout(function() {
resolve();
}, 1000);
});
The first important part, as stated by Yoni, is to tell Heroku that you only need a background worker and not a web worker:
worker: node <path_to_your_worker>
The second important part is: Heroku will launch a web dyno by default. This causes the application to crash if your application does not bind to the port on which web traffic is received. To disable the web dyno and prevent the crash, run the following commands from the commandline in your directory:
$ heroku ps:scale web=0 worker=1
$ heroku ps:restart
This should fix the problem!
It looks like your Procfile contains a "web" process type.
Your Procfile should look something like this:
worker: node <path_to_your_worker>
I deployed an app on Heroku: myapp
and I wrote some cron code in it:
var time = require('time');
var CronJob = require('cron').CronJob;
var job = new CronJob({
cronTime: '00 45 12 * * *',
onTick: clearReserve,
start: true,
timeZone: 'Asia/Shanghai'
});
My purpose is call the function named 'clearReserve' everyday in the specific time.
but it only work in the first day I upload my code to heroku, and never do this cron job again.
PS: this "clearReserve" function will manipulate my database, I use MongoLab URI which I created in MongoLab, not the Heroku add-on;
Your cron job is never ran again because Heroku dyno went to sleep. https://devcenter.heroku.com/articles/dynos#dyno-sleeping
In order to have your cron jobs executed you need to keep Heroku app awake 24/7. To make sure your Heroku app does not go to sleep, install the NewRelic Heroku Addon you can set up availability monitoring. You provide a URL which NewRelic pings every 30 seconds, therefore keeping your app awake. The intended purpose of this feature is to alert you if your site goes down for business and performance reasons, but it has the added benefit of preventing your app from idling.
Hope it helps!
My current situation is that I use grunt to make a production version of my express app (minimize and merge all the js/css, copy all the files in place) and then I have to run a script which sets an environment variables (my app only serves the test harness when running in TEST mode), creates an empty Mongo test database and then calls npm start on the application directory, and then I manually have to run the tests from either Chrome or Phantom, what I want to do is have grunt set the environment variable and run the server, run the tests, and then stop the server (in the future if all is successful it would be nice to have it deploy as well). However when I try to run the app in grunt, it gets stopped as soon as it is completed.
How do I have grunt start the app, wait until it is started and then run tests?
If you check grunt-express which is a plugin for express web-server tasks via grunt.
express-keepalive
Note that this server only runs as long as grunt is running. Once
grunt's tasks have completed, the web server stops. This behavior can
be changed by appending a express-keepalive task at the end of your
task list like so
grunt.registerTask('myServer', ['express', 'express-keepalive']);
Now when you run grunt myServer, your express server will be kept alive
until you manually terminate it.
Such feature can also be enabled ad-hoc by running the task like grunt express express-keepalive.
This design gives you the flexibility to use grunt-express in
conjunction with another task that is run immediately afterwards, like
the grunt-contrib-qunit plugin qunit task. If we force express task to
be always async, such use case can no longer happen.
From the guide grunt-contrib-qunit package is used to run QUnit unit tests in a headless PhantomJS instance. Also mind the last line, if you force express to be always async it would be of no use.
npm link for grunt-express.
I'm not sure if I understand your problem correctly, but probably this helps:
Do you know about Grunt's async function? For some time I used the following approach to start (and stop) my Express app. I used it with watch, so it automatically restarted on save. In this case you have to set watch's nospawn option to true.
var server = null;
grunt.registerTask('server', 'Start server', function() {
var done = this.async();
if (server !== null) {
server.close();
clearCache();
}
var app = require('./my-express-app.js');
server = http.createServer(app).listen(app.get('port'), function(){
done();
});
});
function clearCache() {
for (key in require.cache) {
if (key.indexOf(__dirname + '/node_modules/') == -1) {
delete require.cache[key];
}
}
}
It is ugly because of this require-cache-hack. However, it works.