Sailsjs - Hook orm taking too long to load - Modulus - node.js

I have made a nodejs application using sails.js. It's working perfectly in my localhost. The problem appears in production when I try to publish it in the server(modulus). You can take a look the error below.
Error: The hook `pubsub` is taking too long to load.
Make sure it is triggering its `initialize()` callback, or else set `sails.config.pubsub._hookTimeout to a higher value (currently 20000)
at tooLong [as _onTimeout] (/mnt/data/1/ApiDevConf-master/node_modules/sails/lib/app/private/loadHooks.js:92:21)
at Timer.listOnTimeout (timers.js:110:15) { [Error: The hook `pubsub` is taking too long to load.
Make sure it is triggering its `initialize()` callback, or else set `sails.config.pubsub._hookTimeout to a higher value (currently 20000)] code: 'E_HOOK_TIMEOUT' }
I have tried to figure out how to solve the problem but nothing works. I was trying somethink like this here.
Also I have properly set the NODE_ENV = production
Thanks for your time.

It sounds like this could be one of two issues.
1.) You need to set your migrate setting in config/model.js to something besides alter. You should have migrate: 'safe' on in production mode. This should happen automatically if the NODE_ENV variable is set to production.
The reason it times out is every time you start the server Sails will try and migrate your existing data to the current schema. Obviously don't want this in production.
2.) You have a lot of files to load and Modulus is slow to read them from it's virtual disk. This is a bigger issue because it will take a very long time for your server to start each time you need to restart it. You can bump the global timeout limit and that should give you more time. To do that add the following to your config/env/production.js file:
module.exports = {
hookTimeout: 40000
}

Related

How to use `index.js` in a Node.js when creating an Express service?

Hi I am structuring my Node.js project based on this, like so:
Root
product name
index.js: (contains requires for the product and the main export)
productName.js: contains application logic
test
test1.js
test2.js
...
Now I have two questions
What should logically go in index.js? At the moment I have this (would this be a good way to do things and what else might I include in index.js?):
// index.js
var myServer = require('./myServer.js'); // "product name" = "myServer"
module.exports = {
run: myServer.listen
}
Does it matter what I call the object key in module.exports (currently "run")? Why does the server always run when I execute index.js with $ node index.js how does it automatically know to run myServer.listen?
P.S.: I am aware of web structure auto-generation tools, I just wish to understand the logical reason for this suggested structure (the idea of not having any logic in index.js)
As you mentioned this is a Express service, if it is only handling backend of some application or more specifically this is only backend application, I would suggest you change name of your index.js to server.js(Thus explicitly stating that it'll process all service requests).
But if not then even index.js is fine.
Now for
1
What you've put is absolutely fine, apart from this you could require all modules, routes(or controllers whatever you name them) in a way that it serves as entry point to your application. Try not to put any logic in here.
2
Actually the server runs because it executes the script in the file called index.js, the script says myServer.listen, now if you had written console.log("Hello World") and used $ node index.js it would've printed Hello World instead.
Node just expects and executes script that is there in index.js, in your case it is to start the server.
About the logic that why not put anything else in index.js, for me the reasoning I consider good enough is it provides abstraction as it is the entry point I don't want index.js to worry about things like what to do with this data and all. I believe it should provide a base to setup server. Thus following single responsibility to some extent. Also I won't have to touch it ever in projects lifetime unless some major change occurs e.g. I decide to shift from express to something else.
EDIT
Why have a key called run
You seem to have answered it yourself(in comments), you are giving or more proper description would be you're attaching an object to module.exports as it is a object similar to JSON it was supposed to have a key(which could be anything not necessarily run it could've been hii). Now if you don't want to pass a key and export only one thing that is server.listen then you could write same as module.exports = myServer.listen; instead of
module.exports = {
hii: myServer.listen
}
Note that you could export more modules using the way you did. For more details about module.exports refer this or better google about it as this link might expire anytime and does not seem an ideal thing to put on SO.

webdriver-sync running asynchronously?

I'm trying to create selenium tests that run each step synchronously, without using .then(), or async/await. The reason for this is that I want to create a set of functions that allow pretty much anyone on our test team, almost regardless of tech skills to write easy to read automated tests. It looks to me like webdriver-sync should give me exactly what I want. However, the following dummy code is producing problems:
var wd = require('webdriver-sync');
var By = wd.By;
var Chromedriver = wd.Chromedriver;
var driver = new Chromedriver;
driver.get('https://my.test.url');
var myButton = driver.findElement(By.cssSelector('[id*=CLICK_ME]'));
myButton.click();
It tries to run - browser is launched, and page starts to load... but the steps are not executed synchronously - it goes on and tries to find and click "myButton" before the page has finished loading, throwing a "no such element" error... which to me kinda defeats the point of webdriver-sync?! Can someone tell me where I am going wrong?
FWIW, I have webdriver-sync 1.0.0, node v7.10.0, java 1.8.0_74, all running on CentOS 7.
Thanks in advance!
You need to put double-quotes around "CLICK_ME" as it's a string value.
Generally, though, it's a good idea to Wait for specific elements because dynamic pages are often "ready" before all their elements have been created.

Unable to determine function entry point

Been using MS botframework for a couple months. Developing with the emulator in node and using continuous integration to push to Azure.
Pushed last Wednesday and tested with no problems. Made two very inconsequential code changes and pushed on Friday and no I'm getting:
Exception while executing function: Functions.messages. mscorlib: Unable to determine function entry point. I tried redeploying the older version, same thing.
Thoughts?
The function entrypoint is determined based on this logic. As you can see, the flow is:
If an explicit entry point is defined in function.json, use that
Otherwise; if there's a single exported function, use that
Otherwise; try to use a function named run or index (in that order)
I suspect you were in branch #2, and your minor change introduced new functions, so the runtime is now attempting to locate a function named run or index and that doesn't exist.
Can you please make sure your primary entry point function is named run or index and try again?
Turns out there was a short-lived bug in the Azure git integration and I deployed during the window this bug was live. It modified function.json and left it in an invalid state. Kudos to MS Support for staying with the issue and determining the root cause.
In my case, the root cause is having 1 named export & 1 default export.
To fix this, only export default 1 thing in the entrypoint file (index.js in my case)
Leaving here as a trail in case someone faces the same thing
1) Try stopping the service in Azure:
2) Then go to Kudu: https://[YourAzureSiteName].scm.azurewebsites.net/DebugConsole
and run npm install:
3) Then restart the service in Azure
You can use module.exports for example:
module.exports = async function queryDatabase() {
const pg = require('pg');
//...
//...
}
if you are exporting multiple functions
for example function1, function2 then
by adding this line to the end of file we can resolve this issue.
exports.index = function1

SailJs is Deleting Data from pg database

Something strange is happening with my app, I am using SailsJs with official PostgreSQL driver and my data gets deleted. I don't have any pattern or list of specific events which deletes the data but I have following observations.
Few days back i was writing a function to destroy data and when I
executed that function it gave me an error I fixed the error and ran
my web app again and whoa data from one of my table was all gone.
Yesterday i wrote a function and I tried to get the HTTP call to that
function but it was giving me 500 server error, I started debugging it
and after executing my program 3 to 4 times with this error partial
data was deleted from one of my database table. Later the error was i
had a typo in URL.
If any of you guys had any experience with what is happening to me please let me know how to fix it? or at least help me on how to reproduce this issue ?
EDIT
I activated the logs and was waiting for it to happen again and it happened again and here is the log from sailsjs
In the logs I saw that its talking about alter.js sync strategy but i have selected it to be the safe strategy
It has happened to me quite a few times, when lifting the app and it is in the process of making changes to the db and it fails, sometimes due to ORM timeout.
What sails do when its lifting and needs to update the data structure is controlled in config/models.js migrate: 'alter', usually commented out, you get a prompt for what to do 1... 2... 3... (writing from the top of my head, i dont remember the actual messages) and a warning about using alter on a production system.
Changing
config/orm.js to have this
// config/orm.js
module.exports.orm = {
_hookTimeout: 60000 // I used 60 seconds as my new timeout
};
And for reasons I don't know changing config/pubsub.js
// config/pubsub.js
module.exports.pubsub = {
_hookTimeout: 60000 // I used 60 seconds as my new timeout
};
has helped me, avoid data loss.

Can't connect to MongoDB database with NodeJS native driver

I have a NodeJS app in which I need to connect to to MongoDB databases - one a single server set up, and the second from a replica set. I connect to the next one just fine, but when connecting to the second one - I get the following error:
/Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/db.js:299
throw err;
^
TypeError: Cannot set property 'auto_reconnect' of undefined
at /Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js:110:35
at Array.forEach (native)
at Options.decorateAndClean (/Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js:108:16)
at new exports.ReplSet (/Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js:84:31)
at /Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/mongo_client.js:320:30
at /Users/iddogino/Documents/RapidApp/node_modules/mongodb/lib/mongodb/db.js:296:11
at process._tickDomainCallback (node.js:459:13)
The code I use to connect (after omitting user names and real urls) is:
require('mongodb').MongoClient.connect("mongodb://password#url1:port1,url2:port2/dbName?replicaSet=setName&w=0&readPreference=secondary", function(err, doc) {...});
Now when I tried this alone (not after the code connecting to true other DB), I worked just fine... Any ideas?
This one took me a minute to figure out. The error says the problem is in ./node_modules/mongodb/lib/mongodb/connection/repl_set/options.js:110
The issue is that options.js:91 creates an empty object. They're doing this make a dictionary and deduplicate the 'host:port' strings for the servers. options.js:104 loops through the keys in that dictionary and blindly loads them into an array. This would be a problem if you have added something to Object.prototype globally since it would also get added to the final array of servers. Since whatever you've added to Object.prototype probably isn't a server, it won't have an options property and you'll get this error.
Work around:
Figure out where in your code you have modified Object.prototype and make it less general. I think they've updated this in newer versions of the driver, but if you're using an old one you need to work around it.

Resources