Meteor / NodeJS run own code before migration start (Meteor startup) - node.js

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);
});

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.

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.

grunt task is not executing after deploying to heroku

I have a sails application which I created using the steps in the sailscasts and it works correctly in development.
But when I push it to heroku, the grunt task does not execute and the css and javascript is not linked.
I have registered the following task in the Gruntfile.js
grunt.registerTask('heroku:production', 'build');
My node version is 0.12.7 and sails version is 0.11.0
This might be related to
https://github.com/balderdashy/sails/issues/1872
but I'm not sure how to fix it.
Any help is appreciated.
The problem here that Sails has hardcoded tasks to be called. If you take a look into lib/hooks/grunt/index.js you will see initialize method that calls your tasks.
initialize: function (cb) {
sails.log.verbose('Loading app Gruntfile...');
if(sails.config.environment === 'production') {
return this.runTask('prod', cb);
}
this.runTask('default', cb);
}
So you must have two tasks with prod and default names.
If I'm not mistaken, Heroku runs your application in a production mode, so you must have your prod task (even if you modify something, you must modify prod task), but not the heroku:production.

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

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.

Sail.js requires server restart after running command to refresh database

From this question, Sails js using models outside web server I learned how to run a command from the terminal to update records. However, when I do this the changes don't show up until I restart the server. I'm using the sails-disk adapter and v0.9
According to the source code, the application using sails-disk adapter loads the data from file only once, when the corresponding Waterline collection is being created. After that all the updates and destroys happen in the memory, then the data is being dumped to the file, but not being re-read.
That said, what's happening in your case is that once your server is running, it doesn't matter if you are changing the DB file (.tmp/disk.db) using your CLI instance, 'cause lifted Sails server won't know about the changes until it's restarted.
Long story short, the solution is simple: use another adapter. I would suggest you to check out sails-mongo or sails-redis (though the latter is still in development), for both Mongo and Redis have data auto expiry functionality (http://docs.mongodb.org/manual/tutorial/expire-data/, http://redis.io/commands/expire). Besides, sails-disk is not production-suitable anyways, so sooner or later you would need something else.
One way to accomplish deleting "expired records" over time is by rolling your own "cron-like job" in /config/bootstrap.js. In psuedo code it would look something like this:
module.exports.bootstrap = function (cb) {
setInterval(function() { < Insert Model Delete Code here> }, 300000);
cb();
};
The downside to this approach is if it throws it will stop the server. You might also take a look at kue.

Resources