@brunofuster

www.wesaveapp.com

Archive for the ‘expressjs’ Category

scaling sessions properly on express

leave a comment »

When using sessions on Express you should be careful. The default behavior with app.use(express.session()) is to save the session on any response even if you don’t need it.

From ExpressJS docs:

Properties on req.session are automatically saved on a response

First of all: Redis

Instead of using the default in-memory implementation from Connect, you should start by using a distributable in-memory storage like Redis.

Redis To Go has a free 5MB plan if you want to get started on the cloud.

$ npm install connect-redis

var RedisStore = require('connect-redis')(express)
  , session_store = new RedisStore({host: 'redistogo.com', port: 6379, pass: 'password', prefix: 'appsess:'});

var session = function() {
  return express.session({ store: session_store, secret: 'salt' });
}


Default but wrong usage

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(session());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

Now use apache bench to stress test your unlogged home page:
$ ab -r -n 5000 -c 50 http://127.0.0.1/

Redis should now have 5000 leaked keys waiting for its expiration, consuming huge amount of unnecessary memory.



Per-request session: the real deal

Just load and save the session object when you really need!

Remove app.use(session()) from app.configure!

//without session
app.get('/', function(req,res) {}); 

//with session
app.get('/admin', session(), function(req, res) {});

Delete all Redis keys.
Run the apache bench command again and check your Redis memory totally unused.

Advertisements

Written by brunofuster

June 21, 2012 at 6:56 pm

Posted in cloud, expressjs, redis

deploying a node.js project on cloudfoundry (mac osx)

leave a comment »

If you don’t have your cloudfoundry credentials create here: www.cloudfoundry.com

I’ve run into a bug using Mac’s ruby. If you already use rvm and ruby 1.9.2, you can skip the first step. Found the bug solution here.

Setting up Ruby

Install rvm:

$ bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )

Add the following lines to ~/.bash_profile

# Ruby Version Manager
[[ -s “$HOME/.rvm/scripts/rvm” ]] && . “$HOME/.rvm/scripts/rvm”

Update your terminal env with source or open a new terminal

$ source ~/.bash_profile

Now install ruby 1.9.2

$ rvm install 1.9.2
$ rvm use 1.9.2

Configuring cloudfoundry

Install the vmc gem

$ gem install vmc

Set the target

$ vmc target api.cloudfoundry.com

Login with your credentials… vmc will ask for your email and password.

$ vmc login

Creating a simple express app

* You need Node.JS and NPM from now on

$ sudo npm install express jade
$ mkdir sample-project
$ cd sample-project
$ express

Start your app to check its running:

$ node app.js

Open http://localhost:3000 and see the Welcome to Express msg :)

Configuring your app to run on cloudfoundry

Install cloudfoundry module

$ npm install cloudfoundry

Change your app.js to run locally and at the cloudfoundry

$ vi app.js

Require the cloudfoundry module

var cloudfoundry = require(‘cloudfoundry’);

Go to the app.listen line at the end of the file and change to:

app.listen((cloudfoundry.port || 3000), (cloudfoundry.host || ‘localhost’));

Create a file called package.json and put the used modules:

*jade is the view engine

{
    “name”:”sample-app-bfuster”,
    “version”: “0.0.1”,
    “dependencies”: {
        “express”:””,
        “cloudfoundry”:””,
        “jade”:””
    }
}

Bundle those modules into your project

$ npm bundle

Deploy your app

$ vmc push

Console output:

Would you like to deploy from the current directory? [Yn]: y
Application Name: sample-app-bfuster
Application Deployed URL: ‘sample-app-bfuster.cloudfoundry.com’?
Detected a Node.js Application, is this correct? [Yn]: y
Memory Reservation [Default:64M] (64M, 128M, 256M, 512M or 1G)
Creating Application: OK
Would you like to bind any services to ‘sample-app-bfuster’? [yN]: n
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (33K): OK
Push Status: OK
Staging Application: OK
Starting Application: OK

Running app: http://sample-app-bfuster.cloudfoundry.com
source: https://github.com/bfuster/cf-sample-app

Written by brunofuster

October 27, 2011 at 11:54 am