Grunt - Is it possible to have a task that only runs once ever? - node.js

There is a particular task that I want to run only once and then guarantee that it is never run again. Has anyone done this? I was looking at using grunt.event.once(...), or try and detect folders or files using a shell script on postinstall, but both ways leave a task in the gruntfile.js that could potentially be invoked at any time overwriting files.
At a very simple level it would do something like this:
grunt.registerTask('setup', [
'mkdir' // run some setup tasks
]);
grunt.event.once('setup', function() {
// some how do what's below here so it can't be done again
// so not available in config for reuse and possibly overwriting
// modified files
grunt.task.run([
'bowercopy:src_codeigniter'
]);
});
This even possible in Grunt? I know it's just a task runner, in this case I just want it to run it once.

There are several libraries that let you access a Gruntfile's content via an API so you could use one of these to alter your setup task's configuration after it is run the first time.
There's Gruntfile Editor and Gruntfile API
While both of them don't support complete task removal you can always modify your tasks configuration this way.

Related

How to prevent Mocha from preserving require cache between test files?

I am running my integration test cases in separate files for each API.
Before it begins I start the server along with all services, like databases. When it ends, I close all connections. I use Before and After hooks for that purpose. It is important to know that my application depends on an enterprise framework where most "core work" is written and I install it as a dependency of my application.
I run the tests with Mocha.
When the first file runs, I see no problems. When the second file runs I get a lot of errors related to database connections. I tried to fix it in many different ways, most of them failed because of the limitations the Framework imposed me.
Debugging I found out that Mocha actually loads all files first, that means that all code written before the hooks and the describe calls is executed. So when the second file is loaded, the require.cache is already full of modules. Only after that the suite executes the tests sequentially.
That has a huge impact in this Framework because many objects are actually Singletons, so if in a after hook it closes a connection with a database, it closes the connection inside the Singleton. The way the Framework was built makes it very hard to give a workaround to this problem, like reconnecting to all services in the before hook.
I wrote a very ugly code that helps me before I can refactor the Framework. This goes in each test file I want to invalidate the cache.
function clearRequireCache() {
Object.keys(require.cache).forEach(function (key) {
delete require.cache[key];
});
}
before(() => {
clearRequireCache();
})
It is working, but seems to be very bad practice. And I don`t want this in the code.
As a second idea I was thinking about running Mocha multiple times, one for each "module" (as of my Framework) or file.
"scripts": {
"test-integration" : "./node_modules/mocha/bin/mocha ./api/modules/module1/test/integration/*.integration.js && ./node_modules/mocha/bin/mocha ./api/modules/module2/test/integration/file1.integration.js && ./node_modules/mocha/bin/mocha ./api/modules/module2/test/integration/file2.integration.js"
}
I was wondering if Mocha provides a solution for this problem so I can get rid of that code and delay the code refacting a bit.

Meteor / NodeJS run own code before migration start (Meteor startup)

is there a possibility to execute own code inside a Meteor / Node application before the migrations run?
I know about Meteor.startup but this code runs after the DB Migrations afaik.
Edit: The migrations package i use idmontie:migrations#1.0.3
The migration package you use doesn't seem to support that. If, however, you are able to switch to the more common percolate:migrations then you can fully control when the migration happens, because you actually need to call it explicitly, e.g.,
Meteor.startup(() => {
/* the code you want to run first here.. */
Migrations.migrateTo('latest');
});
In the past, I've even done things like this, where I was running some code between migrations to certain versions:
Meteor.startup(() => {
/* some code to run before ... */
Migrations.migrateTo(3);
/* some code to run in between... */
Migrations.migrateTo(5);
});

How to automigrate when needed in loopback 3?

I created an automigrate script under /bin in my loopback app and added its path in the package.json file so that I can run this script to automigrate whenever I want from the terminal.
I also have a boot script "createUsers.js" which creates some default users in a model. The problem is, whenever I run this script it calls the boot script and it tries to create the users while automigration is still not finished, resulting in a failed automigration. I don't understand why the boot scripts are called when I only run automigrate script specifically. I could call automigrate in the boot scripts and wrap the createUsers.js code in its callback (as shown here), but that would automigrate every time the app is started which is undesirable since the data is lost on automigration. Where should I call automigrate() so that it can be called whenever required? Any help is greatly appreciated.
What I normally do, is create a script called util.js inside boot
util.js
class util{
static _automigrate(){
//Whatever you need to do
}
}
module.exports = function (server) {
global.util = util;
};
This way your script is available across the entire application. And you can call it whenever you need to.
You could call it with
util._automigrate();
I normally use this pattern to store all my input validations etc since I might need those across different models.

Node-cron in multiuser environment

I am trying to create an app using node, in which users can schedule certain cron jobs ,the setting for these job I am fetching from the users and saving it to mongoDB .I need my app to be such that users can start stop these jobs whenever they want . I have a class created which is something like this
Class Croncreator {
constructor () {Creates the cron job}
startCron ()
stropCron()}
Now all this is working ,but I cannot wrap my head around how do I manage this in a multi user environment?
Do I create an instance of this class in my express route for "/api/savecronjob" ,if yes then how do I manage the start stop feature .Considering the fact that 1 user may be creating multiple jobs a time and switching them on off when ever he wants.
I solved the problem by using a NPM package called cron-job-manager.
Read more about it NPM LINK
The documentation is pretty self explanatory .
I basically created a function to create the cron jobs with a identifier,and created two routes to start and stop these jobs.

Is there a way change a node.js while it's running?

Is there a way change a node.js while it's running?
Like edit the javascript files while it's running and then it change accordingly while it's running.
Yes.
You'll have to load your file through another file that watches the script for changes. You will probably need some setup/teardown code that runs in the script whenever it is restarted.
var fs = require('fs');
var file = 'file.js';
var script;
function loadScript() {
if (script) {
if (typeof script.teardown === 'function') {
script.teardown();
}
delete require.cache[file];
}
script = require(file);
}
fs.watch(file, function(event, filename) {
if (event !== 'change') return;
loadScript();
});
loadScript();
The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.
Have you checked Node-supervisor
No, it is not possible. When you startup a Node server / app it will load in the current versions of the files. If you make a change after startup it will be unaware. You will have to kill the app and restart for these changes to take affect.
There are some utilities like node-dev which do this for you. They monitor the filesystem for changes and restart the app as needed (along with some other features like growl notification).
I prefer restarting the app manually. That way you know exactly what version it's running, and can save changes to a file multiple times before deciding to try it out again.
You can use nodemon.
nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.
Perfect solution to work with Node during development.
This is totally possible.
Just don't require your modules in the header; instead, load them by calling at the time of need.
In addition, you can also call require.undef('./myModule') to ditch existing versions before including the new module. You can scan the file system for any new module names, if you feel like dropping in new behavior at runtime.
I have implemented the plugin pattern numerous times with node, such that a submodule update will include new plugins that will be picked up at runtime.
Enjoy.

Resources