11 Things to Consider Before Deploying Your Rails Application

November 16th, 2009

At VinSol, we have been developing and deploying Rails applications for more than four years. During this period, we  have identified some best practices that we prefer to follow while deploying  rails application to production server.

Below is the checklist of these practices:

 

1. Ensure that NS records and MX records are changed if they need to be changed

Changing nameservers will point the domain to the hosting server,  and changing MX records will redirect incoming mails to the mail server. As a very first step, we should make sure that name servers of the domain are set to be the correct one.  Changing MX record is a must if our application is parsing incoming mails or we wants to use other mail services for e-mail exchange, for example Gmail.

 

2. Ensure some backup mechanism in place for both data as well as user uploaded content like images/documents etc.

Since production data is very critical, we must setup backup  mechanism. It could be some type of scheduled task that takes periodic backup of all critical data, Or it could be some type of backup service provided by hosting company. When we talk about critical production data, it includes production DB, content generated by application users like images, documents, etc.

 

3. Ensure database indexes

We might have done development without having proper database indexes, but we should avoid going to production without them. Adding indexes might slow down insert queries a bit but it increases the  performance of read queries. It applies when application in production has percentage of read operations much more than write operations.

 

4. Enable your slow query log

This is specific to MySQL. Enabling slow query log allows MySQL to log slow running queries to a file. And this log can be used to find queries that take a long time to execute and are therefore candidates for optimization.

 

5. Ensure exception capturing is in place

We might want to be notified when something bad happens to our application. There are several hosted services available who receive and track exceptions, for example Hoptoadapp.com, GetExceptional.com etc…  Either we can choose one from these hosted services or we can use “exception notifier” plugin.

 

6. Ensure adding entries for cron/scheduled jobs

Most of the applications have some functionality/jobs that need to be run periodically, for example generating invoices, sending newsletters etc.  In most cases these jobs are done by a rake task. We should make sure that we have added such jobs to cron or similar program.

 

7.  Monitoring important processes

To ensure that our site is up 24×7 we need to ensure that all processes that our application needs are up. There can be many processes like MySQL, Mongrel, Apache etc.. These processes are very important as our application directly depends on them. For example if MySQL process get killed accidentally, our application would not be able to connect to MySQL and will start throwing exceptions.

We can choose any of the available monitoring tools like God, Monit, 24×7 etc…

 

8. Ensure confidential data filtering

We would never like to leak/share confidential information of our application users. We should make sure that none of the user’s confidential data like SSN, Credit card info, password are being written to log files. We might not have paid much attention on this while developing the application.

 

9. Rotate log files

Once our site is up and running, every single request write some text in log file. And hence size of the  log file keeps on increasing. Larger log files can put us in trouble if we get it beyond certain size. Its difficult to manage these log files, as larger files need more memory to open and need more time to download. In one of the rescue project we did , the log file size was 3GB.

We would recommend having logrotate setup for the application.

 

10. Setup Asset Host

Setting up asset hosts can reduce loading time by 50% or more. We must setup asset hosts for our application. Once asset hosts are all set, our static files will be delivered via asset hosts for example asset1.hostname.com, asset2.hostname.com

 

11. Clearing up stale sessions

We should make sure we should not left any stale session on the server. If our application is using DB or file system  as session store, we must add a schedule task to delete stale sessions.

These are some of the points we have identified from our past experience and we might be missing some. Feel free to  always add them as comments, and I’ll keep this post updated.


Akhil is a senior software engineer working with Vinsol for last 5 years. He is an inhouse deployment ninja.

 

 

We also provide affordable rails deployment services.

 

 

10 little known ways to find a ruby on rails team for your next project

November 12th, 2009

Everytime we talk to our clients, we find that they are not aware of lot of options through which they can find a good rails developer. Usually clients go to odesk and other freelance websites to find rails developers. Following are  10 more ways to find  rails company/developer for your next dream project :

  1. Post your requirements on twitter with hashtag #ruby #ror #rails
  2. Go to Railsdevelopment.com - its a directory of rails companies. You can search for specific services with your budget ranges.
  3. Working with Rails – Again a directory of rails developers and companies. You can browse through specific industry categories.
  4. Local Ruby Meetups – The most passionate guys are always there in local meetups. For eg: we have delhi ruby meetups and you can find all local meetups in australia here
  5. RubyJobs – Post a job on rubyjobs or rubyinside job board. There are some country specific ruby job boards.
  6. RubyonRails wiki – There is a wiki of ruby on rails companies.
  7. Open Source Contributions – Sites like http://agilewebdevelopment.com/ gives you a directory of rails plugins. Open Source contributions such as releasing a Rails plugin, or fixing bugs on projects , or Rails itself, demonstrates exposure to other Rails code bases and quality of a developer. Search for developer name in github.
  8. Conferences – Conferences are good way to find quality rails developer or team.
  9. Facebook – Few people post jobs on facebook.

Few tips :

  • Don’t hire someone that doesn’t know Rails at all. Yes, we have seen some people doing it.
  • Ask for references of previous clients if possible in your country.
  • Look for someone who values the money you are paying them and will make your investment in them provide a valuable return.
  • A personal Rails blog is a good indicator of  developer’s interests , experience and resume.

Integrating Yahoo! BOSS with your rails application

October 29th, 2009

What is Yahoo! BOSS? Yahoo developer website cites it as:

“Yahoo! Search BOSS (Build your Own Search Service) is an initiative in Yahoo! Search to open up Yahoo!’s search infrastructure and enable third parties to build revolutionary search products leveraging their own data, content, technology, social graph, or other assets. This release includes Web, News, and Image Search as well as Spelling Suggestions.”

Some of the possible implementation of Yahoo! Boss may be finding related posts for your article, suggested tag/category for an article/query, correcting misspelled words by providing suggestions, fetching latest news on a topic dynamically, search over delicious tags, customized language search. Some of these have been tried and successfully implemented. An example is the TechCrunch’s Search Engine.

Here is a concise guide on how to use this new service in your next rails application.

Obtain API key

Get an application key from http://developer.yahoo.com/search/boss/.

Install BOSSMan Gem

BOSSMan is a gem for interaction with the Yahoo BOSS web service written by John Pignata. Install it using the following commands:

gem install gemcutter
gem tumble
gem install bossman

Usage

Put this in your environment.rb

require 'bossman'
include BOSSMan
BOSSMan.application_id = <Your Application ID>

Web Search

Use the following code to execute search over the web:

boss = Search.web("Apple Pie", { :count => 2, :filter => "-hate" })
puts "Number of results: #{boss.totalhits}"

boss.results.each do |result|
  puts "#{result.title}"
  puts "#{result.dispurl}"
  puts "#{result.abstract}"
end

# => Number of results: 2618888
# => <b>Apple</b> <b>pie</b> - Wikipedia, the free encyclopedia
# => <b>en.wikipedia.org</b>/wiki/<wbr><b>Apple</b>_<b>pie</b>
# => English <b>apple</b> <b>pie</b> recipes go back to the time of Chaucer. <b>...</b> The basis of Dutch <b>apple</b> <b>pie</b> is a crust on the bottom and around the edges. <b>...</b>

boss = Search.web("Moon", { :count => 10, :type => "nonhtml,-pdf" })

boss.results.each do |result|
  puts "#{result.title}"
  puts "#{result.dispurl}"
  puts "#{result.abstract}"
end

# => BACKGROUND:
# => www.<b>radford.edu</b>/~rusmart/<wbr><b>moon</b>.doc
# => We noticed was that one of the scan lines took longer to scan the <b>moon</b> then any other. This occurred toward the middle of the <b>moon</b>. <b>...</b>

boss = Search.web("Star", { :sites => "wwe.com", :style=>'raw' })
boss.results.each do |result|
  puts "#{result.title}"
  puts "#{result.dispurl}"
  puts "#{result.abstract}"
end

# => John Cena - WWE: Raw
# => www.<b>wwe.com</b>/super<b>star</b>s/raw/<wbr>johncena
# => Official profile from WWE for the professional wrestler John Cena, who has been training since he was 15. Features lots of photos and video clips, including John ...

Apart from universal arguments mentioned at the end of this document, the following arguments can also be used:

Parameters Values/Description
:filter Filter out adult or hate content
Syntax: :filter => "-hate, -porn"
:type Specifies document formats (pdf, msoffice,etc)
:view Syntax: :view => "view1,view2", etc

:view => "keyterms" will retrieve related words and phrases for each search result.

:view => "searchmonkey_feed" will retrieve structured data markup, if available, for the search result in dataRSS format.

:view => "searchmonkey_rdf" will retrieve structured data markup, if available, for the search result in rdf format.

:view => "delicious_toptags" will retrieve the top public delicious tags for a document and the counts associated with each tag

:view => "delicious_saves" will retrieve the number of times a document was saved in delicious

:view => "language" identifies the language of the document

:abstract :abstract => "long" will retrieve and display an abstract of a web document up to 300 characters. This expanded abstract provides the requestor with a larger piece of information to work from in a web search query. The default for abstract is an abbreviated description.

Click here to view list of response fields returned by web search.

Images Search

For searching images on web, use the following code:

boss = Search.images("snow hills", { :dimensions => "large" })

boss.results.each do |result|
  puts "#{result.url}: #{result.abstract}"
end

# => http://www.amanita-photolibrary.co.uk/photo_library/BI_habitats/gb96_chiltern_hills_from_ivinghoe_snow_std.jpg: Copyright © 2004 Chiltern hills east from near Ivinghoe snow habitats landscapes British Isles

Click here for list of additional arguments that can be provided with image search.

Click here to view list of response fields returned by image search.

News Search

Yahoo! BOSS also provides news search capabilties.

boss = BOSSMan::Search.news("free shipping", { :age => "1d-2w", :orderby => "date", :count => 1})

boss.results.each do |result|
  puts "#{result.title} [from #{result.source}]"
  puts "#{result.abstract}"
end
# => Wal-Mart announces weekly price cuts for holidays [from USA Today]
# => Wal-Mart said it will cut prices this holiday season for a week at a time on thousands of items, from bananas to board games. The first group of cuts hit Wednesday.

Click here for list of additional arguments that can be provided with news search.

Click here to view list of response fields returned by news search.

Spelling Search

Correct your misspelled words using its spelling suggestion feature:

boss = BOSSMan::Search.spelling("acknowlegment")
puts boss.suggestion # => acknowledgment

Site Explorer

You can also search for the pages from other sites linking into your site pages.

links = Search.se_inlink("http://mail.yahoo.com", :count => 2)
links.results.map { |result| p result.url }
# => http://www.aol.com/
# => http://groups.yahoo.com/

For displays a list of all pages belonging to a domain in the Yahoo! index, use se_pagedata method provided.

links = Search.se_pagedata("twitter.com", :count => 1)
links.results.map { |result| p "#{result.url} - #{result.abstract}" }
# => http://twitter.com/ - Use Twitter to send status updates (tweets) through your cell phone, instant messenger, or via the Web, and notify friends and followers of the little things <b>...</b>

Universal Arguments for Web, Images and News

Following is the list of most commonly used arguments with web, image and news search. For more comprehensive list click here

Argument Options/Details
:start Ordinal position of first result. First position is 0. Default sets start to 0.
:count Total number of results to return. Maximum value is 50. Default sets count to 10.
:format The data format of the response. Value can be set to either "xml" or "json". Default sets format to "json".
:callback The name of the callback function to wrap the result. Parameter is valid only if format is set to "json". No default value exists.
:sites Restrict BOSS search results to a set of pre-defined sites. Multiple sites must be comma separated. Example: (:sites => "abc.com,cnn.com"). The Images service does not yet support multiple sites.
:view Retrieve additional search data provided by the respective BOSS service. Please see individual chapters to see what view options are available.
:style By default for web search result titles and abstracts contain bold HTML tags around the search term. Use :style => "raw" to remove the bold tags around the search terms in titles and abstracts.

Rails Caching And JavaScript Techniques

September 7th, 2009

Cross posted from darthsid

While implementing caching in a recent rails project I came across some typical caching issues. In a lot of pages the content is same for all users but certain components in them have user specific actions. As an example, I have a page listing all public messages that users have posted(similar to the public timeline in twitter) but actions on those messages are user specific(eg: only owner or admin can delete a message). Also, most of these actions use ajax and the rails authenticity token in them also gets cached resulting in subsequent failures if the session changes. Another issue was that the timestamps in most pages is fuzzy and they become irrelevant if a page gets cached for too long. I could have created separate caches for each user but if the user base really grows managing the caches would become a nightmare and that would still not solve the authenticity token and the timestamp problem. The simplest solution was to use JavaScript, more specifically jQuery.
Read the rest of this entry »

How to Integrate TinyMce with Redbox in 5 steps ?

September 4th, 2009

TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.

Redbox is a library that pops a modal box over a web page, using CSS and javascript, so that you can ask the user a question, or show them something important. The box can be loaded from content already on the page (but hidden), or it can be loaded via AJAX. The contents of the box can be replaced using AJAX, for multi-page forms, and it can be closed easily using a javascript link.

Here is the process for integrating Redbox and tinymce.

Step I:
Install required plugins:

- TinyMce(http://github.com/kete/tiny_mce/tree/master)
- RedBox(http://www.craigambrose.com/projects/redbox)

Step II:
Include javascript files to layout:

  <%= include_tiny_mce_js %>
  <%= javascript_tag "initialize_editor();" %>

Now, add this javascript method which initilizes the text editor. You can specify the options you want for your text editor here.

Javascript:

function  initialize_editor(){
  tinyMCE.init({
    theme:"advanced",
    //mode:"textareas", // this is commented because we do not want to apply the editor to all the text area
     instances. Instead, we will use the class "mceEditor" to specify on which element we want to add the editor.
    theme_advanced_toolbar_location:"top",
    theme_advanced_toolbar_align:"left",
    theme_advanced_resizing:true,
    theme_advanced_resize_horizontal:false,
    paste_auto_cleanup_on_paste:true,
theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",
    theme_advanced_buttons1:"bold, italic, underline, strikethrough, | , undo, redo, link, unlink, image, | , bullist, numlist",
    theme_advanced_buttons2:"",
    theme_advanced_buttons3:"",
    dialog_type:"modal"
  });
}


Step III:


Add editor class “mceEditor” to the text area where you want the editor to be added.

<%= f.text_area :details, :id => 'ta_id', :class => 'mceEditor' %>

Now, we need to create a tinymce editor control for the text area(’ta_id’) on loading the popup so add this “execCommand” loads the tinyMCE in the textarea.

<script type="text\javascript">
  tinyMCE.execCommand('mceAddControl', true, "ta_id");
</script>

Step IV:


When we submit our form and copy over the editor content to the text box it references. Tinymce provides a method ‘triggerSave’ that moves the contents from the editor to the form field. This method is automatically called by tinyMCE by adding a trigger on the forms submit method.

Save the content:

<%= f.submit 'Save', :class => 'primaryAction', :onclick => "tinyMCE.triggerSave(true,true);" %>

Step V:


Whenever we close our popup redbox we need to remove the tinymce editor control that we had added. Remove control on closing the redbox:

<%= link_to_close_redbox 'Close', {:onclick => "tinyMCE.execCommand('mceRemoveControl', true, 'ta_id'});"} %>

Works on: Firefox(1.5+), Safari and IE(7+)

For Internet Explorer we need to initialize the editor on loading the pop-up but for firefox we need to initalize editor on loading the main page. So we need modify our javascript

<script type="text\javascript">
  if(navigator.appName=="Microsoft Internet Explorer")
  	initialize_editor();
  tinyMCE.execCommand('mceAddControl', true, "ta_id");
</script>

And so here we are ready to go in just five simple steps.

Refer here for more details.