How to create application level variable in node.js - node.js

In my project I have running more than 100 cron jon using npm cron. My problem is I need to stop any cron job at run time.
my code is
in app.js file
var cronJobRunner =require('cronJobHandle.js');
global.jobManager = {};
cronJobRunner.startServiceFromCronJobManager("service 1")
in cronJobHandle.js
var CronJob = require('cron').CronJob;
module.exports = {
startServiceFromCronJobManager: function (scheduleServiceName) {
var serviceList =['service1','service2','service3','service4']
serviceList.forEach(function(service){
var job = new CronJob('* * * * * *', function(){
console.log("Service running");
}, function () {
// This function is executed when the job stops
},
true /* Start the job right now */,
timeZone /* Time zone of this job. */
);
global.jobManager.service = job;
});
},
stopServiceFromCronJobManager: function (scheduleServiceName) {
console.log(global.jobManager);
global.jobManager[scheduleServiceName].stop();
}
};
router.js
var cronJobRunner =require('cronJobHandle.js');
app.route('/stopservice',function(req,res){
cronJobRunner.stopServiceFromCronJobManager("service1");
}
When I call http://localhost:9999/stopservice
I am getting undefine in console.log(global.jobManager);
Please help me how to maintain cron jobManager variable comman for all server side js files

It is global but there's two bugs in your code.
1) you're calling the property called "service" instead of the one whose name is in service.
Change
global.jobManager.service = job;
to
global.jobManager[service] = job;
2) you're pottentially using global.jobManager in cronJobHandle.js before to declare it in app.js
There's a better solution. you don't need and should use global. Just declare a standard variable in cronJobHandle.js instead (so that it isn't accessed by other modules):
var jobManager = {};
...
jobManager[service] = job;
...
jobManager[scheduleServiceName].stop();

Related

NPM cronJob - dynamically set time

here is my code for scheduling a task. i have used separate routes for starting,stopping and changing the time as given below. please tell me if its correct. and also im getting an error for changing the time frequency.please help me.
const cronjob=require('cron').CronJob
var first='* * * * * *'
var task=function() {
console.log('last'+job.lastDate()+' next '+job.nextDates(1));
}
var complete=function(){
console.log('the end.........')
}
var job = new cronjob(first,task, complete, false, 'Asia/Kolkata');
app.get('/start',(req,res)=>{
job.start()
console.log('is job running? ', job.running);
res.send('cron started')
})
app.get('/set',(req,res)=>{
var time=req.headers.time /* input taken from user for changing the frequency*/
time='30 5 1-31 0-11 1-7' /*hard-coded temporary for testing*/
console.log(time)
job.setTime(time)
})
/set api is throwing an error
/Error: time must be an instance of CronTime./
we have to use instance of a cronTime i.e.
const CronTime = require('cron').CronTime
.
.
.
var time=req.query.time
//time='*/5 * * * * *'
job.setTime(new CronTime(time))
res.send('time changes')

How to use forever-monitor with Electron-Angular project?

I am using Angular 2 with Electron and want to keep running a process in background to show notifications. I am using forever-monitor for that, it works only in development mode, but when I package my app using electron-packager, this stops working. My code looks like that:
main.ts
exports.runBackgroundProcess = () => {
// Run a background process forever
var forever = require('forever-monitor');
var child = new(forever.Monitor)('src/assets/notification-process.js',
{
env: {ELECTRON_RUN_AS_NODE: 1},
options: []
});
child.start();
}
I wrote a function in main.ts that will run background process when called from angular component. Code in notification-process.js is following:
notification-process.js
notifier = require('node-notifier')
notifierFun = (msg) => {
notifier.notify({
title: 'Notify Me',
message: msg,
wait: true
});
}
var CronJob = require('cron').CronJob;
new CronJob('* * * * * *', function() {
notifierFun("Message from notification process");
});
Finally I am calling the function from app.component.ts
let main_js = this.electronService.remote.require("./main.js");
main_js.runBackgroundProcess();
I don't think it is a good idea to set your script in the assets directory.
I would prefer it to be packaged as an extra resource.
the next snippet will permit to launch your node process
var child_process = require('child_process');
var child = child_process.fork('notification-process.js',[],{
cwd : 'resources'
});
If it does not work once packaged, this may be involved because your files have not been packaged .To package it as an extra resource, modify package.json as follow :
this will package webserver folder to resources/webserver folder:
"target": [
"win": {
"target": "nsis",
"icon": "build/icon.ico",
"extraResources" : [{
"from" : "webserver",
"to" : "webserver"}
]
},
for reference, have a look at :
https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options
That's how it worked:
1- Moved notification-process.js file from assets folder to main directory.
2- Changed file path in main.js:
var child = new (forever.Monitor)(path.join(__dirname, 'notification-process.js')...
Without using join, it doesn't work after packaging the app.

Trouble writing a file with CronJob in Heroku using writeFileSync()

I am trying to repeatedly update a file using a cronjob. Eventually, this is going to be more complicated but for now I'm trying to figure out my current problem. I know the code below is somewhat over-complicated because I preserved the basic structure while trying to problem solve. Here is the server file:
// server.js
var express = require('express');
var port = process.env.PORT || 8080;
var http = require('http');
var fs = require("fs");
var curtainup = require('./diagnoseleak.js');
var url = require("url" );
var app = express();
// launch ======================================================================
app.listen(port);
//run the CronJob
var CronJob = require('cron').CronJob;
new CronJob('0 * * * * *', function() {
console.log("running");
var date = new Date();
console.log("Ran at: "+date.getHours()+":"+date.getMinutes());
curtainup.doitnow();
} , null, true, 'America/New_York');
And here is the file referenced called diagnoseleak.js:
var fs = require("fs");
var mostRecentLocation = "./config/pullfiles/mostRecent55.txt";
module.exports = {
doitnow: function(){
var writethefile = function(){
fs.writeFileSync(mostRecentLocation, "A file called mostRecent55 should be create with this text", { flag: 'w' });
console.log("This should write to the console");
}
writethefile();
}
}
From the directory that houses the server file, I type the following into cmd:
git add .
git commit -m "adding files"
git push heroku master
heroku run bash
Then into the bash window I type:
cd config/pullfiles
ls -l
AND...no file called mostRecent55.txt appears. Am I looking in the wrong place? Eventually I want to be able to update a file, but I have a feeling I'm either looking in the wrong place for this mostRecet55.txt file or going about the process of writing it incorrectly.
heroku doesn't let you write files onto the filesystem where your app is stored. You would need to use an add-on, database or external service of some kind. The only exception seems to be /tmp which is only temporary storage

jasmine with gulp, run tests on test file changed

Hi what I trying to do is to make watcher task with gulp which will run my jasmine tests. What I have done so far:
var watch = require("gulp-watch");
var jasmine = require("gulp-jasmine");
gulp.task('tests.run.change-watcher', function (cb) {
gulp.src(testsFiles)
.pipe(watch(testsFiles))
.pipe(jasmine({ verbose: true }));
});
But when I run that task and try to change any file which meets the testsFiles rules it doesn't show anything in console.
However when I run the next task:
gulp.task('tests.run', function (cb) {
gulp.src(testsFiles)
.pipe(jasmine({verbose:true}));
});
It works and shows next:
8 specs, 0 failures Finished in 0 seconds
Maybe I miss something?
Do it in two steps
1) Declare the test-unit task (like you did)
gulp.task('tests.run', function () {
return gulp.src(testsFiles)
.pipe(jasmine({verbose:true}));
});
2) Declare the watch task that will run this test-unit task when those testsFiles change
gulp.task('tests.watch', function () {
gulp.watch(testsFiles, ['tests.run']);
});
Then, you run gulp tests.watch
To run only needed specs, try something like this:
/** Watches file changes in source or spec files and executes specs automatically */
gulp.task("specs-watcher", function() {
return watch(["src/**/*.ts", "spec/**/*.ts"], { events: ["add", "change"] }, function(vinyl, event) {
if (!vinyl.isDirectory()) {
if (vinyl.basename.endsWith(".spec.ts")) {
// We are dealing with a spec file here, so call jasmine!
runJasmine(vinyl.path);
} else {
// Try to find out specs file
const specFilePath = findSpecsFile(vinyl);
if (typeof specFilePath === "string") {
runJasmine(specFilePath);
}
}
}
});
});
This watcher uses two functions, one is for deriving the spec name based on the file name. In my case, it's:
/**
* For your specs-watcher: This function is called every time a file changed which doesn't end with '.spec.ts'.
* The function's task is to return the fitting specs path of this file. For example by looking for a corresponding file in the "/spec/" folder.
* #param {vinyl} changedFile Vinyl object of changed file (see https://github.com/gulpjs/vinyl)
* #return {string|undefined} Path to the specs file to execute or undefined if your watcher shouldn't do anything.
*/
function findSpecsFile(changedFile) {
return changedFile.path.replace(__dirname, `${__dirname}/spec`).replace(".ts", ".spec.ts");
}
The other function is runJasmine, which runs jasmine with a given test file.
Just make everything fit to your setup and it should work. :-)
You can listen to file changes for both tests and source code folders with this:
"use strict";
var gulp = require('gulp');
var mocha = require('gulp-mocha');
var batch = require('gulp-batch');
gulp.watch(['tests/**', 'src/**'], batch(function (events, cb) {
return gulp.src(['tests/*.js'])
.pipe(jasmine({ verbose: true }))
.on('error', function (err) {
console.log(err.stack);
});
}));
gulp.task('default', () => {
console.log('Gulp is watching file changes...');
});

Execute a function in a new process node

I am looking for a way (a npm module or a lib would be really useful) to run a javascript function in a new process. However, I don't want to define this function in a different file. I am looking for something like the POSIX fork mechanism.
how can I achieve this in node?
You can fork new processes using child_process.fork. It accepts a separate module, but if you must have it all contained in one file you could give your script a mode parameter:
var child_process = require('child_process');
var mode = process.argv[2] ? process.argv[2] : 'default';
var modes = {
default: function() {
console.log('I am the default, I will fork a child');
child_process.fork(__filename, ['child']);
},
child: function() {
console.log('I am the child!');
}
};
modes[mode]();

Resources