How to create schedule cron job in loopback, where can I code? I tried to implement node-schedule but not work. I don't know how to call my controller code?
To solve this I've used a workaround: I've created a public endpoint and a cron job that call that endpoint using https://cron-job.org/
Hope that it helps :)
@anandrajputSF can you explain your requirements in detail?
@hacksparrow basically my requirement is connect with sql server, after some time interval fetch data from tables and log some where, if next time cron run, it will pick data from log table last run time and from this time it will again fetch data from sql server
@anandrajputSF LoopBack does not provide an in-built solution to your specific usecase, however with Remote hooks it can be very well achieved.
@anandrajputSF were you able to solve your problem?
@hacksparrow i haven't try.
@anandrajputSF I have implemented something similar in loopback, you can do it the way you would do it in NodeJS and its nothing specific to loopback.
You can use this package : https://www.npmjs.com/package/cron
And you can paste the code in your controller file or a file in the boot folder. Here is some example code :
`'use strict';
const CronJob = require('cron').CronJob;
module.exports = function (app) {
function runCron() {
//The code which you want to run in the cron job
}
var job = new CronJob({
cronTime: '00 00 10 * * 0-6', // The Time at which you want the cron job to run
onTick: runCron,
start: false,
timeZone: 'Asia/Kolkata'
});
job.start();
}`
Hope this Helps !
@nikhil-g777 This seems to be a great solution if the application is running on a single instance. But if I have more instances running the same time they will run the same cron job multiple times.
@matteo-pennisi
You could use environment variables to keep one of the instances as the main instance with an instanceNumber as 1, which would run the cron job
if(process.env.instanceNumber == 1)
{
job.start();
}
This is more like a workaround, but I believe it should solve the problem
It would be awesome if LB would have a way to inject a component, as a service or repository, in a cron component. Also invoke a self rest endpoint.
This solution has worked for me.
https://www.npmjs.com/package/node-cron
$ npm install --save node-cron
import { CronController } from "./controller/cron.controller";
const cron = require('node-cron');
export class Cron {
constructor(
protected cronController: CronController,
) {
}
async start() {
this.eachMinute();
}
private async eachMinute() {
console.log('Start Cron Jobs');
cron.schedule('* * * * *', async () => {
await this.cronController.start();
console.log('running a task every minute');
});
}
}
// index.ts
export async function main(options: ApplicationConfig = {}) {
const app = new MyApplication(options);
await app.boot();
await app.start();
const url = app.restServer.url;
console.log(`Server is running at ${url}`);
console.log(`Try ${url}/ping`);
// Instanciate CronController
const cronController = app.controller(CronController);
// Get Instance
const cronControllerInstance = await cronController.getValue(app);
// Inject by constructor
const cron = new Cron(cronControllerInstance);
// Invoke method
cron.start();
return app;
}
@dtelaroli Does that mean that the cron is only run on one instance?
@filipef101 you can have multiple instances into the CronController or multiples Controllers into the Cron. It's up to you, but I think that is easier into the CronController, otherwise you should inject manually multiple controllers.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.
Just for reference, there is a package called Bull that allows assigning an ID to the Job. If running multiple instances, attempting to create a job with an ID that already is in the queue will be ignored.
https://github.com/OptimalBits/bull
This solution has worked for me.
Installation
https://www.npmjs.com/package/node-cron $ npm install --save node-cronCreate a component
import { CronController } from "./controller/cron.controller"; const cron = require('node-cron'); export class Cron { constructor( protected cronController: CronController, ) { } async start() { this.eachMinute(); } private async eachMinute() { console.log('Start Cron Jobs'); cron.schedule('* * * * *', async () => { await this.cronController.start(); console.log('running a task every minute'); }); } }Using Loopback DI Container to get a controller instance:
// index.ts export async function main(options: ApplicationConfig = {}) { const app = new MyApplication(options); await app.boot(); await app.start(); const url = app.restServer.url; console.log(`Server is running at ${url}`); console.log(`Try ${url}/ping`); // Instanciate CronController const cronController = app.controller(CronController); // Get Instance const cronControllerInstance = await cronController.getValue(app); // Inject by constructor const cron = new Cron(cronControllerInstance); // Invoke method cron.start(); return app; }
This solution worked for me as well. Loopback 4 tested. Example in repo: https://github.com/tangoat2019/covid19-tracking-api
Most helpful comment
This solution has worked for me.
Installation
Create a component
Using Loopback DI Container to get a controller instance: