Wednesday, June 13, 2007

How to export data from one database and import into another.

mysqldump -u root -p myapp_staging some_table > mytable.sql

and then

mysql -u root -p myapp_acceptance < mytable.sql

Rails Refactoring to Resources - Using CRUD and REST in Your Rails Application

Nice book from Apress written by Trotter Cashion. I finished reading this book last night. It has a very good coverage of the RESTful goodness in Rails. Short and sweet. Learned a lot from this book. Very well written. I give it 4.5 out of 5 stars. The reason is ActiveResource in the latest Rails is not discussed in the book.

Saturday, June 09, 2007

svn: Out of date: '/trunk' in transaction '2-1

When I commit the changes to the svn, I got:
svn ci .
Sending .
svn: Commit failed (details follow):
svn: Out of date: '/trunk' in transaction '2-1'
svn: Your commit message was left in a temporary file:
svn: '/Users/balaparanj/work/zepho/ard/svn-commit.tmp'

Out of date here means the repository version is not the same as the local version. It works after doing svn up.

Tuesday, May 15, 2007

Rails Performance Screencast notes

Here is the notes I took notes from topfunky's httperf screencast.

Production Log Analyzer is a gem that lets you find out which pages on
your site are dragging you down.

Change one thing at a time and benchmark. Take actual data from
production db, export it and use it for benchmarking. Create a
separate environment for benchmarking.

Install httperf. Need 2 machines one for running httperf client and
the other for running Rails app.

Shut down all unnecessary programs on both machines to reduce CPU
usage. This reduces unpredictable results.

Process for Benchmarking Webapplication using Httperf

1) rake sweep_cache
2) mongrel_rails start -e production (no logging)
3) Hit a particular page once
4) run httperf (with consistent args)

Step 1 and 2 is run on Rails app machine. Go to browser on the client
machine load the page and run:

httperf --server machine_name --port 3000 --ur /page_name --num-conns 1000

The number of connections parameter can be changed. In the output of
the httperf make sure that you get number of replies is same as total
connections. Reply status should not have any errors. If there are any
httperf errors the results must be tossed out.

Copy the "Reply rate" line of the httperf output for different number
of connections and use topfunky's script to generate graphs.

./script/parse_httperf_log log/httperf-sample-log.txt

Tuning Mongrel for Performance

Here are the steps for finding how many requests per second a single
Mongrel process can handle.

httperf --server machine_name --uri /page_name --port 3000 --num-conns
7000 --rate 650 --hog

650 is the requests/sec

If this process hangs for more than 20 secs then we have overloaded
Mongrel. Httperf should have no errors (because it means httperf was
overloaded, in that case data must be tossed out).

Try different values for number of connections and rate, such as 6600,
660, 6700, 670 etc. Till the reply rate reaches a maxium and begins to
drop off.

Scaling Rails - Notes from Silicon Valley Ruby on Rails Meetup

Some websites are launched by getting it on TechCrunch, Digg, Reddit
etc. In such cases there is no time to grow organically.

Resources:

1. The Adventures of Scaling Rails -
http://poocs.net/2006/3/13/the­adventures­of ­scaling­stage­1
2. Stephen Kaes "Performance Rails" - http://railsexpress.de/blog/f
iles/slides/rubyenrails2006.pdf
3. RobotCoop blog and gems -
http://www.robotcoop.com/articles/2006/10/10/the­sof
tware­and­hardware­that­runs­our­sites
4. OReilly's book "High Performance MySQL

This presentation's focus is on what's different from previous
writings. For comprehensive overview refer the above resources.

Scribd.com was in launched in march, 07. It is the "YouTube" for
documents and it handles around 1 Million requests per day.

Current Scribd Architecture

1 Web Server
3 Database Servers
3 Document Conversion Servers
Test and Backup machines
Amazon S3

Server Hardware

Dual, dual core woodcrests at 3 Gz
16 GB of memory
4 15K SCSCI hard drives in a RAID 10
Disk speed is important. Don't skimp; you're not Google, and it's
easier to scale up than out.
Hosted by Softlayer.

Software

CentOS
Apache/Mongrel
Memcached, RobotCoop's memcache-client
Stefan Kaes' SQLSessionStore - This is the best way to store peristent sessions.
Monit, Capistrano
Postfix

They ran tests and found out that fragment caching improved
performance for their web app.

How to Use Fragment Caching

Consider only the most frequently accessed pages.
Look for pieces of the page that don't change on every page view and
are expensive to compute

Just wrap them in a
<% cache('keyname') do %>
...
<% end %>
Do timing test before and afterwards; backtrack
unless significant performance gains

Expiring fragments - 1. Time based

Use memcached for storing fragments
It gives better performance
It is easier to scale to multiple servers
Most importantly: It allows time­based expiration

Use plugin http://agilewebdevelopment.com/plugins/memcache_fragments_with_time_e...
Dead easy:
<% cache 'keyname', :expire => 10.minutes do %>
...
<% end %>

Expiring fragments - 2. Manually

No need to serve stale data
Just use: Cache.delete("fragment:/partials/whatever")
Clear fragments whenever data changes
Again, easier with memcached

They also discussed about how to use 2 database servers with Rails
app. For more information you can see the slides at
http://www.scribd.com/doc/49575/Scaling-Rails-Presentation

Q & A

They use SWF open source plugin for uploading documents (it allows
multiple docs to be uploaded simultaneously)

They pay only $100 monthly for Amazon S3 for 5 tera bytes of b/w
usage. Downside of using Amazon S3 is that they cannot generate
analytics for that part of the app.

The uploaded files goes to a queue and is processed in the background.
So the documents don't appear immediately on the site if the load is
high.

Tip from the first presentation on CacheBoard: It uses backgroun drb
plugin by Ezra for exporting documents in XML format.

Tuesday, May 01, 2007

Configuring Selenium to Run Automated Tests

Had to dig out this buried info on Selenium to get the browser to run the automated tests.

Also the Selenium tests are not independent of each other. The tests within a particular file depend on what page the previous test has ended. Strange but if you don't know this you will end up spending lot of time banging your head against the wall.

Colorizing ZenTest output

To get the green and red color for autotest:

1. sudo gem install --remote Redgreen
2. put the statement: require 'redgreen' in the environment.rb

restart the autotest if is already running. Now you will have green color for passing scenario and red for failing tests. Enjoy!

Monday, April 30, 2007

Tests : Before

21:32:17:~/clients/brep/td/trunk > rake stats
(in /Users/balaparanj/clients/brep/td/trunk)
/Users/balaparanj/clients/brep/td/trunk/config/boot.rb:38:Warning: require_gem is obsolete. Use gem instead.
+----------------------+-------+-------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers | 1158 | 972 | 28 | 118 | 4 | 6 |
| Helpers | 329 | 283 | 0 | 42 | 0 | 4 |
| Models | 975 | 759 | 25 | 127 | 5 | 3 |
| Libraries | 733 | 552 | 9 | 82 | 9 | 4 |
| Components | 0 | 0 | 0 | 0 | 0 | 0 |
| Integration tests | 0 | 0 | 0 | 0 | 0 | 0 |
| Functional tests | 701 | 522 | 52 | 106 | 2 | 2 |
| Unit tests | 493 | 382 | 26 | 62 | 2 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total | 4389 | 3470 | 140 | 537 | 3 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
Code LOC: 2566 Test LOC: 904 Code to Test Ratio: 1:0.4

ssh: somedomain.org: No address associated with nodename

This error message happened while remote login using ssh. ping command did not work. The problem was the domain was incorrect.

Saturday, April 28, 2007

Ruby: No such file to load -- ubygems (LoadError)

I deleted the contents of directory site_ruby and I was getting that error message. After some googling found Rich Kilmer's reply

"You have installed rubygems and set the RUBYOPT variable. This is the
downside to using the RUBYOPT :-(

Just unset that variable and then you should be good to go."

-rich

Thanks Rich, that fixed my problem.

rmagick headache on mac os

Finally resolved the rmagick installation problems. The actual problem was not rmagick itself but a custom script in my project.

I found the RMagick install script for Mac OS X - Version 0.2.0
on rmagick installation faq.

/opt/local/bin/ruby: bad interpreter:

I was getting the weird ruby bad interpreter error message after I deleted everything under site_ruby directory. I was working on getting the rmagick working on my laptop. I resolved the problem by reinstalling the Ruby 1.8.6 and Rubygems 0.9.2.

Friday, April 27, 2007

warning: multiple values for a block parameter (0 for 1)

In the following irb session the error message indicates that the input parameter is missing.

>> hello = lambda { "hello" }
=> #
>> hello.call
=> "hello"
>> log = lambda { |str| puts "[LOG] #{str}" }
=> #
>> log.call
(irb):16: warning: multiple values for a block parameter (0 for 1)
from (irb):17
[LOG]
=> nil
>> log.call("A test log message")
[LOG] A test log message
=> nil

Friday, April 20, 2007

Capistrano Concepts

Chris Selmer's Capistrano Presentation from the April 5, 2007 DCRUG
meeting is very good.

The Rails Edge conference had discussion on the material
covered in this presentation, but this presentation connected all the
dots for me.

Copying to the clipboard in UNIX

You can send any output to the clipboard by using pbcopy. For example: history | pbcopy will send the output of history command to the clipboard. You can just paste it in email or other document. Very nice. pbpaste will paste the contents of the clip board.

Tuesday, March 20, 2007

How to create drop down boxes in Ruby on Rails

Migration file : 001_create_people.rb

class CreatePeople < ActiveRecord::Migration
def self.up
create_table :people do |t|
t.column :first_name, :string
t.column :last_name, :string
t.column :email, :string
t.column :created_at, :datetime
end
end

def self.down
drop_table :people
end
end

person.rb
class Person < ActiveRecord::Base
has_many :tasks
end

task.rb
class Task < ActiveRecord::Base
belongs_to :user

def self.find_all_person
Person.find(:all, :order => "first_name").map {|u| [u.first_name, u.id] }
end

end

tasks/_form.rhtml

<h2> Create a Task for a Person</h2>
<% form_for ( :task, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
Title:        <br>
        <%= f.text_field :title, :class => 'text_field' %><br>
    </p>
    <p>
    
Content:
        <br>
        <%= f.text_field :content, :class => 'text_field' %><br>
    </p>

        <br>
        
        <p>Select a priority:
    
          <%= f.select ( :priority, %w { 1 2 3 4 5 6 7 8 9 10 } ) %>
    
        </p>
    </p>

    Person:
            <br>
            <%=
             f.select ( :people_id, @people )
            %>

        </p>
    
    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

tasks/edit.rhtml
<h1>Editing task</h1>

<%= error_messages_for :task %>

<% form_for ( :task, :url => task_path ( @task ) , :html => { :method => :put } ) do |f| %>
  <p>
    <%= submit_tag "Update" %>
  </p>
<% end %>

<%= link_to 'Show', task_path ( @task ) %> |
<%= link_to 'Back', tasks_path %>

tasks/index.rhtml
<h1>Listing tasks</h1>

<table>
  <tr>
  </tr>
  
<% for task in @tasks %>

<tr>
    <td><%= link_to   ( h task.title ) ,    task_path ( task ) %></td>
  </tr>

<% end %>
</table>

<br />

<%= link_to 'New task', new_task_path %>

tasks/new.rhtml
<h1>New task</h1>

<%= error_messages_for :task %>

<%= render :partial => 'form', :locals => { :path => tasks_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>
                                            

<%= link_to 'Back', tasks_path %>

tasks/show.rhtml

<h2>Task </h2>
    <p> Title: <%=  h @task.title %></p>
    <p>Content: <%= h @task.content %></p>
    <p>Priority: <%= h @task.priority %></p>
    <p>Created At: <%= @task.created_at %></p>
    <p>Person: <%=  @person.first_name %></p> -->
    
<%= link_to 'Back', tasks_path %>

people/_form.rhtml

<% form_for ( :person, :url => path, :html => { :method => method } ) do |f| %>
    <p>
    
    <strong>First Name: </strong>
        <br>
        <%= f.text_field :first_name, :class => 'text_field' %><br>
    </p>
    <p>
    
    <strong>Last Name: </strong>
        <br>
        <%= f.text_field :last_name, :class => 'text_field' %><br>
    </p>

    <strong>Email: </strong>
        <br>
        <%= f.text_field :email, :class => 'text_field' %><br>
    </p>

    <p>
        <%= submit_tag button_text %>
    </p>

<% end %>

people/edit.rhtml
<h1>Editing person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => person_path ( @person ) ,
                                            :method => :put,
                                            :button_text => 'Update' }
%>


<%= link_to 'Show', person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

people/index.rhtml
<h1>Listing people</h1>
* Create an application to track a person's tasks. The user should be able to
create people, create tasks, and assign a task to a person when the task is created.

<table>
  <tr>
  </tr>
  
<% for person in @people %>
<tr>
    <td><%= link_to   ( h person.first_name ) ,    person_path ( person ) %></td>
  </tr>
  
<% end %>
</table>

<br />

<%= link_to 'New person', new_person_path %>

people/new.rhtml
<h1>New person</h1>

<%= error_messages_for :person %>

<%= render :partial => 'form', :locals => { :path => people_path,
                                              :method => :post,
                                              :button_text => 'Create' } %>


<%= link_to 'Back', people_path %>

people/show.rhtml

<h2>Person </h2>
    <p>First Name: <%=  h @person.first_name %></p>
    <p>Last Name: <%= h @person.last_name %></p>
    <p>Last Name: <%= h @person.email %></p>

<%= link_to 'Edit', edit_person_path ( @person ) %> |
<%= link_to 'Back', people_path %>

home/index.rhtml
<%= link_to  "People",    :controller => :people, :action => :index %><br>
<%= link_to  "Tasks",    :controller => :tasks, :action => :index %>

layouts/people.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>People: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

layouts/tasks.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Tasks: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>

<p style="color: green"><%= flash[:notice] %></p>

<%= yield  %>

</body>
</html>

controllers/home_controller.rb
class HomeController < ApplicationController
def index

end
end

people_controller.rb
class PeopleController < ApplicationController
# GET /people
# GET /people.xml
def index
@people = Person.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @people.to_xml }
end
end

# GET /people/1
# GET /people/1.xml
def show
@person = Person.find(params[:id])

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @person.to_xml }
end
end

# GET /people/new
def new
@person = Person.new
end

# GET /people/1;edit
def edit
@person = Person.find(params[:id])
end

# POST /people
# POST /people.xml
def create
@person = Person.new(params[:person])

respond_to do |format|
if @person.save
flash[:notice] = 'Person was successfully created.'
format.html { redirect_to person_url(@person) }
format.xml { head :created, :location => person_url(@person) }
else
format.html { render :action => "new" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# PUT /people/1
# PUT /people/1.xml
def update
@person = Person.find(params[:id])

respond_to do |format|
if @person.update_attributes(params[:person])
flash[:notice] = 'Person was successfully updated.'
format.html { redirect_to person_url(@person) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @person.errors.to_xml }
end
end
end

# DELETE /people/1
# DELETE /people/1.xml
def destroy
@person = Person.find(params[:id])
@person.destroy

respond_to do |format|
format.html { redirect_to people_url }
format.xml { head :ok }
end
end
end

controllers/tasks_controller.rb
class TasksController < ApplicationController
# GET /tasks
# GET /tasks.xml
def index
@tasks = Task.find(:all)

respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @tasks.to_xml }
end
end

# GET /tasks/1
# GET /tasks/1.xml
def show
@task = Task.find(params[:id])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @task.to_xml }
end
end

# GET /tasks/new
def new
@task = Task.new
@people = Task.find_all_person
end

# GET /tasks/1;edit
def edit
@task = Task.find(params[:id])
end

# POST /tasks
# POST /tasks.xml
def create
@task = Task.new(params[:task])
@person = Person.find(:first, :conditions => "id = #{@task.people_id}")

respond_to do |format|
if @task.save
flash[:notice] = 'Task was successfully created.'
format.html { redirect_to task_url(@task) }
format.xml { head :created, :location => task_url(@task) }
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# PUT /tasks/1
# PUT /tasks/1.xml
def update
@task = Task.find(params[:id])

respond_to do |format|
if @task.update_attributes(params[:task])
flash[:notice] = 'Task was successfully updated.'
format.html { redirect_to task_url(@task) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @task.errors.to_xml }
end
end
end

# DELETE /tasks/1
# DELETE /tasks/1.xml
def destroy
@task = Task.find(params[:id])
@task.destroy

respond_to do |format|
format.html { redirect_to tasks_url }
format.xml { head :ok }
end
end
end

Monday, March 05, 2007

sudo: port: command not found

export PATH=$PATH:/opt/local/bin
export MANPATH=$MANPATH:/opt/local/share/man
export INFOPATH=$INFOPATH:/opt/local/share/info

Included the above lines in .bash_profile (my mac is using bash shell) and voila a nagging problem sudo: port: command not found is gone!!!

sudo port -d selfupdate

ran successfully. Now I was able to install FreeImage by running:
sudo port install freeimage

Thursday, March 01, 2007

LoadError: no such file to load — selenium

LoadError: no such file to load — selenium. This kind of error message can happen if you have installed anything as a gem but you have not specified require "rubygems" as the first statement in your program.