Category: nodejs (page 2 of 2)

Q&A: sails.js deploy app and run on port 80

Question

<sickyjim> hi all, I’m trying to run an app on port 80 instead of 1337 but when I change the port in config/env/production, the app launches but I can’t reach it from a browser :/

Answer

This could be caused by a couple of things. We’ll go through each and every one of them. If it’s still not working for you, leave a comment down below and I’ll update the list with more checks.

Port 80 < 1024

When running an application on a port < 1024, you’ll need su access. These ports are “special”, and thus protected behind sudo.

Now please don’t run your application on sudo. In stead, run it on any port > 1024, and in your firewall forward port 80 to the chosen port. For this example I’ve chosen the default port 1337.

Port in use

Something else might be using port 80. Common ones are:

  • Apache – sudo apachectl stop
  • Nginx – nginx -s stop
  • Skype – preferences > Advanced: Change Incoming connections port

If all else prevails, run the following command (for your OS) to find out what’s running on port 80:

MacOS: sudo lsof -i ':80'

Linux: netstat -tulpn | grep :80

SPI protection

It might also be SPI firewall protection blocking your application from functioning. You can read more about that here: SPI Firewall protection on router.

Q&A: Deploying your sails.js application

Question

<ebsarex> hi, I just finished developping a sailsjsapp and would like to deploy it on a dedicated server of mine, does anyone know about a guide to do so or something like this ?

Answer

Yes. The deployment guide for sails can be found here, in the docs but also here on github if you prefer that.

If you’re using a specific hosting provider such as Modulus, NodeJitsu, OpenShift or one of the many others, you can take a look here as well.

Q&A: Sails.js get model definition for enum

Question

<leolrrj> I’ve enum at my model and I want to retrieve it values… there’s a way?

Answer

Sails stores the models under sails.models. For those of you that have the models option set to true in the globals.js config, User.find() could also be written as sails.models.user.find().

Once initialised, the model becomes an object where one of its properties is definition. So in order to retrieve the model’s definition, and in this specific case, the values for the enum, you could simply use sails.models.user.definition.enumfield to retrieve the values.

Survival guide: Many websocket connections

When working with sails.js, or indeed any software that accepts websocket connections, you have to be careful you don’t start rejecting requests. It’s all about finding the perfect balance between CPU, memory and file descriptors. Unfortunately, there is no such thing as a “one size fits all” solution in this case, because it all depends on your application.

I’ll try to highlight the importance of certain aspects by providing examples with them. I’ll explain why, when and how they’re important, providing possible solutions with them as well. For this article I’ll assume you’re using sails.js, but the suggestions given in this article apply to any application. Let’s get to it.

Scaling

Scalability is something to always keep in mind. You can read more about scaling sails.js here.

Horizontal scaling

You can read about this more by reading this article. To me, this is one of the most important things to keep in mind while setting up your server architecture.

The most obvious way to make scaling possible, to me, is by using redis as the session store and pubsub adapter. That way, you’re not memory-bound and you can simply add instances and VMs, where you apply load balancing.

System scaling

This is a pretty simple thing to set up. Using PM2 you’ll be able to scale your application over multiple cores on a single machine. Sometimes, an extra core is cheaper that an extra VM. This all depends on how much memory you’ll need to add, and how much CPU power is actually being used.

Resources

It’s crucial to know exactly how much memory you need, and to keep an eye on how much you’re using. If you have a memory leak, or a sudden increase in activity your application might crash (which can obviously be recovered using forever.js) your application might crash, and we don’t want that to happen. In general, you should be careful with what you store in memory. Just as with memory, it’s also equally as important to keep an eye on your CPU power.

File descriptors

File descriptors, as taken from wikipedia:

In computer programming, a file descriptor (FD) is an abstract indicator for accessing a file.

Everything, even network connections use FDs. By default, the limits set for them are quite low making it quite probable you’ll find yourself looking at errors that only show up in your /var/log/messages log, and don’t make a whole lot of sense. Capping this limit, will cause connections to drop, communications to fail and basically ensures chaos.

Viewing the limits

There are two types of FD limits: system limits and user limits. The system limits can be viewed by running:

the user limits can be viewed by signing in as the user (su username) and running for the hard limit:

And for the soft limit:

Changing the limits

To change the system limits, run:

Open up vi /etc/sysctl.conf and add the following at the end of the file: fs.file-max = 200000.

Finally, run sysctl -p.

For the user, open the file vi /etc/security/limits.conf and add the following lines (replacing username with the username you’re using):

Save the file, and done.

The right limits

Figuring out what the right number is for your server depends on your application. If you notice you’re capping on file descriptors, with plenty of bandwidth, memory and CPU left it’s probably safe to increase the number by quite a bit.

Sails.js enable redis sockets

Socket.io allows you to use redis for sockets. Because sails.js uses socket.io, it consequently also allows you to set up redis for sockets. Enabling this behaviour is relatively easy.

To enable this, open up config/sockets.js and look up this block:

Now uncomment the options, configure the adapter and you’re done.

Q&A: sails.js enable jsonp

Question

This is a question I had myself. Why, if I call /foo?callback=bar do I not get a jsonp response?

Answer

Out of the box, sails doesn’t enable jsonp support. In order to enable this, you have to change config/blueprints.js and add jsonp: true.

Q&A: Sails.js won’t run through forever.js

Question

Since recent releases of sails.js, for some people it seems like sails won’t run using forever anymore.

On github, SuThaw asked:

I installed forever js with “npm install forever -g” and I run it like this “forever start app.js –prod”. when I open up my browser (http:127.0.0.1:1337), nothing shows up.

Answer

The answer, is a new “safety switch” that has been added to migrations. This safety switch protects you from accidentally erasing precious data from your database when changing the properties of models due to database errors. What happens, is that sails asks you a question, that requires user input to be answered and go away (continue the flow). Using forever, this never happens. The message sails gives you is:

Excuse my interruption, but it looks like this app does not have a project-wide “migrate” setting configured yet. (perhaps this is the first time you’re lifting it with models?)

And gives you the following options:

  1. safe – never auto-migrate my database(s). I will do it myself (by hand)
  2. alter – auto-migrate, but attempt to keep my existing data (experimental)
  3. drop – wipe/drop ALL my data and rebuild models every time I lift Sails

To fix this, all you have to do is add a default migrate option in config.models.js. You could, for instance, simply add safe:

Q&A: autoWatch false still pushes updates sails.js

Question

The autoWatch configuration option for blueprints seems to be causing some confusion every now and then. Specifically, the question is:

Why, after disabling autoWatch by setting it to false, do I still receive updates from pubsub?

Answer

Taken from the sails documentation, the option autoWatch allows you to specify:

Whether to run Model.watch() in the find and findOne blueprint actions. Can be overridden on a per-model basis.

The function Model.watch() watches for newly created records for that specific model; not updates. The subscribe method however, is responsible for updates.

Found here, you can see sails uses a different option for pubsub:

If you want to disable pubsub, you can read how to do that on disabling pubsub in sails.

Q&A: Disable pubsub sails.js

I love short, concise blog posts. Let this be one of them!

Question

After having had this question asked a couple of times, I decided it qualified for a dedicated blog post. This particular question has been asked on IRC, a while back on github and in a sense, as well on StackOverflow.

[10:29:53] RWOverdijk: do u know if there is a way to completely shut off the pubsub feature in blueprints?

Answer

In your project’s root, create a file called .sailsrc. Inside of this file, add the following:

Voila, you’ve disabled pubsub.

Javascript dependencies

The never ending journey.

As a lot of you might have had as well, I’ve had a lot of problems with managing my javascript dependencies. There are a lot of ways you can do it, but most of them either require a lot of work, or have too many dependencies to work with.

I’ve searched long and hard, trying to find the best solution. I’ve come across Require.js, browserify, grunt and many more, but these were the best solutions in the bunch. Here are some of my findings on these three.

Require.JS

Require.JS is different in that it’s mainly meant to do AMD loading. It allows you to do some cool things, and actually works quite well. The problems I have with require.js are as follows:

  • It forces you to wrap your code in a function call.
  • It forces another (quite large) dependency on you.
  • It’s difficult to add non-AMD dependencies.
  • When a non-AMD dependency requires the use of another non-AMD file, good luck.
  • When you want to add unit tests you’ll have to work around require.js.

It’s good, but not good enough for me.

Browserify

Browserify looks very appealing when you look at it for the first time. Using require calls in my front-end javascript!? Yes please! Unfortunately, after trying to work around it for quite a while, I’ve found a couple of pretty upsetting drawbacks:

  • It’s a bit fragile and doesn’t always do what you’d expect.
  • It makes generating code coverage a tad difficult (it doesn’t recognize the require calls).
  • It forces a dependency on you.

It’s better than require.js, but still not good enough.

Grunt (concat, usemin)

GruntJS, the task-running bamf. It’s amazing in that grunt itself doesn’t manage your dependencies for you, the plugins do. So this is actually a comparison between two of the best plugins I’ve found.

usemin

Usemin allows you to add good old script tags to your html, and html comments to figure out where to put the combined file. This is pretty cool, but it’s only cool when using static html files as it rewrites your html for you. I was able to still implement this, have it write my views to a different directory and tell my app to use those views. This worked okay, but still felt a bit weird and dirty.

concat

grunt-contrib-concat, the best I’ve found. This plugin is really straight forward. Specify the javascript sources, and where (what file) you’d like to put them. It just concatenates a list of scripts, and allows you to supply wildcards, too (the way grunt does). This is super simple, and actually is all anyone would ever need. Downside? It requires quite a bit of extra work as you’ll always have to update the task in the gruntfile whenever you add a new dependency and also forces you to keep a mapping between those files and the gruntfile so you don’t end up with orphans.

In comes useuses

Tired of looking through all these alternatives I decided it was time to write something myself. I called it useuses because it allows you to use uses. Aren’t I creative?

What it is.

Before I started writing this plugin, I assembled a list of requirements:
* It must be optional.
* It mustn’t force a dependency upon someone.
* It must be “standard”, so no weird tags.
* It must add value to the files, even when not used.

With those requirements set, I came up with a way to specify what dependencies a file has, to make it informative for the developers. So as soon as you were to open up a file, you’d immediately see what it depends on. This made me think of the way jquery ui does that. It’s nice, but not nice enough. It’s still unformatted information.

The syntax

I finally came up with the following syntax:

This is informative and standardized in the docblock format. I immediately added support some other formats:

Conclusion

I liked all alternatives and think that the developers did a great job creating solutions. I think that whatever you decide to use depends on your project’s requirements and development style.

If you wish to give useuses a go, you can find the npm package for useuses by clicking here.

Happy coding.

©SpoonX 2017