Nov 28 2007

Cleaning up Rails Session Records

etienne @ 8:07 pm

Similar:
  • None Found
  • In the Rails Cookbook there is an article describing how to clean up stale session records periodically, i.e. 13.14 Cleaning Up Residual Session Records. When I attempted to set this up as described in the book there was a couple of problems.

    1. I have a few additional require statements in my config/environment.rb which includes some of my custom classes which I’m serializing.

    require ‘app/models/survey_item’
    require ‘app/models/survey_group’

    The problem was that the cron job was failing as it could not find these files so I had to modify the cron job from the suggested

    */10 * * * * ruby /srv/www/htdocs/apps/<appname>/script/runner \
    script/runner -e production SessionCleanup.nuke_old_db_session

    to

    */10 * * * * cd /srv/www/htdocs/apps/<appname> && ruby script/runner \
    -e production SessionCleanup.nuke_old_db_sessions

    2. Now my cron job was running but if was deleting all my sessions, it was as if it was comparing the wrong time so the condition was always true. I use UTC time in my application and realised I had to make a slight modification to the function in the environment.rb that deletes the session records to take this into consideration, so I changed the function from:

    # Clean up session
    class SessionCleanup
      def self.nuke_old_db_sessions
        CGI::Session::ActiveRecordStore::Session.destroy_all(
          [’updated_at < ?’, 20.minutes.ago]
        )
      end
    end

    to

    # Clean up session
    class SessionCleanup
      def self.nuke_old_db_sessions
        CGI::Session::ActiveRecordStore::Session.destroy_all(
          [’updated_at < ?’, 20.minutes.ago.utc]
        )
      end
    end
     

    By adding the .utc to 20.minutes.ago fixed the problem.

     

    Tag: cron, Rails, Ruby

    Nov 22 2007

    Rails Deployment and Installation - Nginx + Mongrel Cluster + Subversion + Capistrano

    etienne @ 7:17 pm

    Ok so I’ve finished my new Rails application and it’s now time to deploy, which has turned out to be somewhat more challenging than I thought. I’m deploying to a dedicated host running SuSe 9.3.

    Installation check list:

    1. Ruby
    2. RubyGems
    3. Rails
    4. Mongrel + Mongrel Cluster
    5. Nginx
    6. Subversion
    7. Capistrano

    So roll up your sleeves and lets get into it.

    1. Ruby

    We will build Ruby using the latest source that we will download from the Ruby web site. Before we can do this we need to do some initial setup which includes making sure the required packages are installed that will allow us to build Ruby from source.

    1. Start YAST, Software, Install and Remove Software

    2. Check if Ruby is already installed, remove it if it is

    3. Install the following packages if they have not already been installed

    • zlib-devel
    • make
    • gcc 
    • openssl
    • openssl-devel

    We then need to download the latest version (1.8.6-p110 at time of writing) of the Ruby source which can be downloaded from the official Ruby web site. Once you have downloaded the source we can start the build process.

    Create a temporary directory where we can save the source and do all of our builds:
    mkdir /tmp/build

    Save the Ruby source file to the new directory and extract all of the files using 
    tar zxvf ruby-1.8.6-p110.tar.gz

    Change into the new source directory created by the extraction process 
    cd ruby-1.8.6-p110

    Setup our make files
    ./configure –prefix=/usr –with–openssl

    Build Ruby
    make

    Install 
    sudo make install

    Check installation worked
    ruby -v
    which should return the Ruby version, e.g. ruby 1.8.6 (2007-09-23 patchlevel 110) [i686-linux]

    Remove the source files
    rm -rf  ruby-1.8.6-p110

    2. RubyGems

    As we do not want to run Rails without installing RubyGems we need to download the source code and build it. Go to RubyForge and download the latest source code (0.9.4 at time of writing).

    Save the source code in the temporary directory we created for Ruby above, i.e.
    /tmp/build

    Extract the source code using
    tar zxvf rubygems-0.9.4.tgz

    Change to the source directory created by the extraction process
    cd rubygems-0.9.4

    Perform the installation
    sudo ruby ./setup.rb 

    Remove source files
    rm -rf rubygems-0.9.4

    3. Rails

    We can now install Rails which is something you may already have done in your development environment. Use the include-dependencies option to make sure all required files are installed.

    Install Rails
    sudo gem install rails –include-dependencies 

    Verify the installation worked
    rails -v
    which returns the Rails version number for example Rails 1.2.5

    4. Mongrel + Mongrel Cluster

    To install Mongrel you will need to have Ruby 1.8.4 (or later) and RubyGems installed.

    Install Mongrel
    sudo gem install mongrel –include-dependencies

    We will be using a cluster of three mongrel processes, you need to decide how many will be suitable for your application. To run a cluster of mongrel processes we need to install the mongrel_cluster gem, for details on this gem see the Mongrel web site.

    Install the Mongrel Cluster gem
    sudo gem install mongrel_cluster

    Now that we have Mongrel and Mongrel Cluster installed we can continue with the configuration. I created a test Rails application to test my setup and make sure everything is working correctly. Later when I install my application I will make the required changes to these configs to work correctly with my "real" application.

    Create the Rails application we will use for testing, I’m placing it in the apache root directory under a new apps directory. To find the document root go to /etc/apache2 and do a grep on documentroot, i.e. grep -i documentroot
    cd /srv/www/htdocs/apps/
    rails testapp

    Create a user that will be used by the cluster
    useradd -system mongrel

    Create a cluster configuration file with three processes using ports 8001, 8002, and 8003. This will create a file in the config directory called mongrel_cluster.yml
    cd /srv/www/htdocs/apps/testapp
    mongrel_rails cluster::configure -p 8001 -e production -a 127.0.0.1 -N 3

    I then modified the default configuration file to look like this:

    user: mongrel
    cwd: /srv/www/htdocs/apps/testapp
    log_file: /var/log/mongrel.log
    port: "8001"
    environment: production
    group: www
    address: 127.0.0.1
    pid_file: tmp/pids/mongrel.pid
    servers: 3

    Change permissions and owner of the Rails application. I am using the same group as used by my Apache system (see /etc/apache2/uid.conf) in my case it’s www
    chown -R mongrel:www /srv/www/htdocs/apps/testapp

    That takes care of the installation and configuration. We can test to make sure the cluster is working by starting it and connecting to it via a browser.

    Start the cluster
    cd /srv/www/htdocs/apps/testapp
    mongrel_rails cluster::start

    Check status of the cluster
    cd /srv/www/htdocs/apps/testapp
    mongrel_rails cluster::status

    Run browser and connect to mongrel ports, you should see the standard Rails startup page
    127.0.0.1:8001
    127.0.0.1:8002
    127.0.0.1:8003

    To stop the cluster
    cd /srv/www/htdocs/apps/testapp
    mongrel_rails cluster::stop

    To restart after a code change for example
    cd /srv/www/htdocs/apps/testapp
    mongrel_rails cluster::restart 

    We need to setup the cluster so that it will be restarted when the server is rebooted. 

    Create a new directory and create a new link to the mongrel cluster configuration file we created in the previous step
    mkdir /etc/mongrel_cluster
    ln -s /srv/www/htdocs/apps/testapp/config/mongrel_cluster.yml \
    /etc/mongrel_cluster/testapp.yml

    Copy the shell script supplied when the mongrel cluster gem was installed to the init.d directory. The shell script allows us to control the cluster including start, stop, status, and restart.
    cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster_1.0.5/resources/mongrel_cluster \
    /etc/init.d/
    chmod +x /etc/init.d/mongrel_cluster
    Usage: /etc/init.d/mongrel_cluster <status|start|stop|restart>

    Add the mongrel cluster as a service
    Add the service:
    chkconfig mongrel_cluster 35
    To check the service:
    chkconfig –list mongrel_cluster
    To delete the service: chkconfig –del mongrel_cluster

    There was one modification I had to make to the mongrel_cluster script to get it to work without any errors: 
    Edit: /etc/init.d/mongrel_cluster
    Change:
    chown $USER:$USER $PID_DIR
    To: chown $USER:$GROUP $PID_DIR 
     

    5. Nginx

    Now that we have a working mongrel cluster running three mongrel processes how are we going to do the load balancing for these processes? I initially looked at using Apache 2.2 + mod_proxy_balancer but as SuSe 9.3 does not have any pre-built packages for 2.2 and I did not want to face the daunting task of building Apache myself I had to look at some alternatives.

    I initially considered Pen and Pound but then came across Nginx which seems to have a lot of positive feedback from users. From what I have read it seems that it only requires a small amount memory and is as fast if not faster than mod_proxy_balancer. So I decided to give it a try and so far I’ve been very happy with it.

    Before we can install nginx we need to install some packages required during the build process.

    1. Start YAST, Software, Install and Remove Software

    2. Install the following packages if they have not already been installed

    • pcre
    • pcre-devel
    • pcre++-devel
    • openssl
    • openssl-devel

    I found that these packages where not available on my installation CD so I used packages I found using rpmfind. I connected to this site from the SuSe machine using Konqueror, which when I clicked on the required package, the package information window was displayed allowing installation via YAST.

    We can now build and install nginx, one point to note is that I’m using the latest snapshot which includes the upstream_fair changes as discussed in Ezra Zygmuntowicz article A Fair Balancer for Nginx and Mongrel 

    Download snapshot from the link below, save the file in the /tmp/build directory
    http://git.localdomain.pl/?p=nginx.git;a=shortlog;h=upstream_fair

    Extract all files 
    tar xzvf nginx-x.x.xx.tar.gz

    Change to the extracted source directory
    cd nginx-x.x.xx 

    Setup our make files
    ./configure –with-http_ssl_module –prefix=/usr

    Build nginx
    make

    Install
    sudo make install

    Check installation worked
    nginx -v
    which should return the nginx version, e.g. nginx version: nginx/0.5.32

    Remove the source files
    rm -rf  nginx-x.x.xx

    Now we need to configure nginx to work with our Rails application, to do this I used a modified version of  Ezra Zygmuntowicz configuration file as described in the Nginx, my new favorite front end for mongrel cluster article. The other change I made to the configuration file was to include the performance improvement tip described in another of Ezra’s articles New Nginx conf with optimization.

    Create the nginx.conf file in the test Rails application config directory

    I changed the ownership and rights of this file to be the same as the other config files, i.e.
    chmod 664 nginx.conf
    chown mongrel:www nginx.conf

    Test nginx config file
    cd /srv/www/htdocs/apps/testapp
    nginx -t -c config/nginx.conf 

    Start nginx using the new config file
    cd /srv/www/htdocs/apps/testapp
    nginx -c config/nginx.conf

    Stop nginx
    ps aux | grep nginx
    kill -15 <pid>
    where <pid> is the pid of the master process

    Test nginx is working correctly, start a browser and connect to nginx using the port you specified in the config file listen directive, i.e. listen 80;. You should see the standard Rails welcome page.

    We now need to setup nginx to run as a service so that it will be restarted when the server is rebooted. To do this I modified a script that I found in a slicehost article Ubuntu LTS - adding an ngnix init script, here is my modified version which I’m sure can be improved on but for now it does what I need it to do. Create this script in the /etc/init.d directory in a file called nginx.

    #! /bin/sh

    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    DAEMON=/usr/sbin/nginx
    NAME=nginx
    DESC=nginx
    PIDFILE=/usr/logs/$NAME.pid
    DAEMON_CONFIG=/etc/nginx/nginx.conf

    test -x $DAEMON || exit 0

    set -e

    case "$1" in
      start)
            echo -n "Starting $DESC: "       
            start-stop-daemon –start –quiet –pidfile $PIDFILE \
                    –exec $DAEMON — -c $DAEMON_CONFIG
            echo " started"
            ;;
      stop)
            echo -n "Stopping $DESC: "
     if [ -f $PIDFILE ]; then
                    kill -15 `cat $PIDFILE 2>/dev/null`
            fi
            echo " stopped"
            ;;
      restart|force-reload)
            echo -n "Restarting $DESC: "
     if [ -f $PIDFILE ]; then
                    kill -15 `cat $PIDFILE 2>/dev/null`
            fi
            sleep 1
            start-stop-daemon –start –quiet –pidfile $PIDFILE \
                    –exec $DAEMON — -c $DAEMON_CONFIG
            echo " restarted"
            ;;
      status)
            echo "Status $DESC: "
            ps aux | grep -v grep | grep -v /bin/sh | grep $NAME
            ;;
      *)
            N=/etc/init.d/$NAME
            echo "Usage: $N {start|stop|status|restart}" >&2
            exit 1
            ;;
    esac

    exit 0

    Steps to configure nginx as a service.

    Create a new directory
    mkdir /etc/nginx

    Create a link to the nginx.conf file in the test Rails application config directory
    ln -s /srv/www/htdocs/apps/testapp/config/nginx.conf \
    /etc/nginx/nginx.conf

    Make the script executable
    chmod +x /etc/init.d/nginx
    Usage: /etc/init.d/nginx <status|start|stop|restart>

    Add it as a service
    Add the service: chkconfig nginx 35
    To check the service: chkconfig –list nginx 
    To delete the service: chkconfig –del nginx

     

     


    Nov 11 2007

    Naming Conventions - Ruby and Ruby on Rails

    etienne @ 10:02 pm

    In  an attempt to see if I can get my "Ruby and Rails Naming Conventions" article back on Google I’ve created this entry to see if it gets listed.

    Click on the link to access the actual article Ruby and Rails Naming Conventions

    Sorry for the inconvenience.

     


    Nov 09 2007

    Ruby and Rails Naming Conventions Article Missing from Search Engines

    admin @ 7:44 am

    Over the past week or two I’ve noticed traffic to my Blog have dropped dramatically. Upon further investigation I have found that traffic to one of the most popular articles "Ruby and Rails Naming Conventions" have almost dropped to zero.

    I’ve checked Google and the other search engines and this article does not appear at all when using the following search terms "rails naming conventions", it use to be one of the top five for quite some time.

    I have searched the Internet to try and figure out why my article is no longer listed, but as yet I’ve not found anything that may explain why this has happened. If anyone has any ideas it would be much appreciated if you could let me know. I’m not sure if I can approach Google about this as this seems to be the same for all search engines.

    Click on this link to access the actual article Ruby and Rails Naming Conventions