tag:blogger.com,1999:blog-56152755738726425802024-03-06T05:46:03.517+05:30Tech learnI love to do coding, configure open source and tech discussion. I always look problem as an opportunity to learn.Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-5615275573872642580.post-8073196005629221772020-05-06T10:00:00.000+05:302020-05-06T10:00:15.110+05:30Errno::ENOSPC: No space left on device<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="p1" style="font-stretch: normal; line-height: normal;">
<span style="font-family: "helvetica neue";"><span style="font-family: "arial" , "helvetica" , sans-serif;">Recently one of our EC2 instance was down due to insufficient disk space. To make it up immediately we had increased its disk space dynamically using EC2 console.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">After debugging we found that there was an unexpected spike in rails logs ( some custom logs also ) and logrotate failed to rotate them due to insufficient memory.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">After increasing memory, we still, getting ‘Errno::ENOSPC: No space left on device’ in some Sidekiq jobs. Every though more than 50% disk space was available.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXs3Vmx7iESkahmcE_EWmGeQ8uZEAFLWmE-DzToTIJT3HUYTqk6_RbPvskkh6BRGYV0YGyqTLa8UfUXW534wZ33pLQJyUfdWscmC309b3hCUFMK5cgbrGGG7RB-PfbTTj46GgjSDINPB_Q/s1600/Screenshot+2020-05-06+at+9.44.46+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="218" data-original-width="480" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXs3Vmx7iESkahmcE_EWmGeQ8uZEAFLWmE-DzToTIJT3HUYTqk6_RbPvskkh6BRGYV0YGyqTLa8UfUXW534wZ33pLQJyUfdWscmC309b3hCUFMK5cgbrGGG7RB-PfbTTj46GgjSDINPB_Q/s320/Screenshot+2020-05-06+at+9.44.46+AM.png" width="320" /></span></a></div>
<span style="font-family: "helvetica neue";"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">After googling, got that might be running out of inodes, but it seems that also not an issue.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXh8hj_kJrQ5qIzjSEi_Ffe7GlW11R-p29AnxseF11sJDc0kjphyYgfd5oYNmF5fRu16tnLR6HR67cG3G9h5HpKouMUtBiAtufP3i0gG2pc1NCH6k4EbSaSOYWtM8QYhTEgdpYrh_xN7D9/s1600/Screenshot+2020-05-06+at+9.45.06+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><img border="0" data-original-height="219" data-original-width="494" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXh8hj_kJrQ5qIzjSEi_Ffe7GlW11R-p29AnxseF11sJDc0kjphyYgfd5oYNmF5fRu16tnLR6HR67cG3G9h5HpKouMUtBiAtufP3i0gG2pc1NCH6k4EbSaSOYWtM8QYhTEgdpYrh_xN7D9/s320/Screenshot+2020-05-06+at+9.45.06+AM.png" width="320" /></span></a></div>
<span style="font-family: "helvetica neue";"><span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">But in the above output found a strength file system for /tmp called 'overflow'. So googled out on that term and got the exact reason for an issue.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">Here is that reason,</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";"><i>When the system boots and the hard drive is full, nothing can write to /tmp. So during init, a tmpfs is created and mounted. This way your system can safely boot because it can write to /tmp.</i></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">So started looking on, how to reset back tmp, found many solutions but those seem to be risky, but out of that found nice solution provided by Jarrod’s blog.</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">He just asked to unmount an overflow partition so that /tmp will go back to the normal pointing.</span></span><br />
<br />
<pre class="shell" name="code">
sudo umount overflow
</pre>
<br />
</span>
<span style="font-family: "helvetica neue";">But after running this command was getting an error,</span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";"><i>umount: /tmp: device is busy.</i></span></span><br />
<span style="font-family: "helvetica neue";"><span style="font-family: "arial" , "helvetica" , sans-serif;"><i> (In some cases useful info about processes that use</i></span></span><br />
<span style="font-family: "helvetica neue";"><span style="font-family: "arial" , "helvetica" , sans-serif;"><i> the device is found by lsof(8) or fuser(1))</i></span></span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue";"><br /></span>
<span style="font-family: "helvetica neue";">Again his blog helped. Found comment in his blog for exactly the above issue.</span></span><br />
<br />
<pre class="shell" name="code">
sudo umount -l /tmp
</pre>
<br />
</span>
<span style="font-family: "helvetica neue";">And finally /tmp got mounted back to normal.</span></span></div>
</div>
Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-8873547831572284782016-05-06T17:45:00.000+05:302016-05-06T17:45:29.530+05:30How to test model validations with validation type<div dir="ltr" style="text-align: left;" trbidi="on">
While reading a code or while doing code review, I have see many times people write a test cases for model validation like this,
<br />
<strong>Before</strong>
<pre class="rails" name="code">
# app/models/post.rb
class Post < ActiveRecord::Base
validates :title, presence: true
end
</pre>
<pre class="rails" name="code">
# test/models/post_test.rb
test "should have the necessary required validators" do
post = Post.new
assert_not post.valid?
assert post.errors.has_key(:title)
# or some times
assert_equal ["can't be blank"], post.errors.messages[:title]
end
</pre>
And if same attribute has more than one validation then,
<pre class="rails" name="code">
# app/models/post.rb
class Post < ActiveRecord::Base
validates :title, presence: true, length: { in: 10..60 }
end
</pre>
Most of the people do,
<pre class="rails" name="code">
test "should have the necessary required validators" do
post = Post.new
assert_not post.valid?
assert_equal ["can't be blank", "is too short (minimum is 10 characters)"], post.errors.messages[:title]
end
</pre>
I think instead we can use <strong>symbol</strong> for it. Rails internally uses I18n locale support for error messages. For more details have a quick look on reference links provided below.
<br/>
<br/>
Means we can take a benifits from it. So improved test case code is,
<br />
<strong>After</strong>
<pre class="rails" name="code">
test "should have the necessary required validators" do
post = Post.new
assert_not post.valid?
assert post.errors.added? :title, :blank
assert post.errors.added? :title, :too_short, { count: 20 }
end
</pre>
While for custom validate method, you can use same approch by defining new key. Key can be any valid symbol.
<br/>
<strong>Before</strong>
<pre class="rails" name="code">
class Post < ActiveRecord::Base
has_many :tags
validates :title, presence: true
validate :validate_tags_count
private
def validate_tags_count
errors.add(:tags, "required alteast 2 tags") if tags.reject(&:marked_for_destruction?).count < 2
end
end
</pre>
<strong>After</strong>
<pre class="rails" name="code">
class Post < ActiveRecord::Base
has_many :tags
validates :title, presence: true
validate :validate_tags_count
private
def validate_tags_count
errors.add(:tags, :required, count: 2) if tags.reject(&:marked_for_destruction?).count < 2
end
end
</pre>
<pre class="rails" name="code">
test "should have the necessary required validators" do
post = Post.new
assert_not post.valid?
assert post.errors.added? :tags, :required, { count: 2 }
end
</pre>
<pre class="rails" name="code">
#config/locales/en.yml
# Globally for all models
en:
errors:
messages:
required: "minimum %{count} tags required"
</pre>
or
<pre class="rails" name="code">
#config/locales/en.yml
# only to post models
en:
activerecord:
errors:
models:
post:
attributes:
tags:
required: "minimum %{count} tags required"
</pre>
Same concept will work on rails 5 as well. Tested with rails 5.0.0.beta4.
<br />
<br />
<b>References :</b><br />
<a href="http://api.rubyonrails.org/classes/ActiveModel/Errors.html" target="_blank"> http://api.rubyonrails.org/classes/ActiveModel/Errors.html</a>
<br />
<a href="https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/presence.rb" target="_blank"> activemodel/lib/active_model/validations/presence.rb</a>
<br />
<a href="https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml" target="_blank">activemodel/lib/active_model/locale/en.yml</a>
<br />
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com2tag:blogger.com,1999:blog-5615275573872642580.post-41452864088921112172015-01-05T16:04:00.000+05:302015-01-06T11:26:53.297+05:30Ruby 2.2.0 installation using rbenv failing<div dir="ltr" style="text-align: left;" trbidi="on">
On my ubuntu 14.04 development machine, ruby 2.2.0 installation using rbenv was failing with following error<br />
<pre class="rails" name="code">
➜ ~ rbenv install 2.2.0
Downloading ruby-2.2.0.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/7671e394abfb5d262fbcd3b27a71bf78737c7e9347fa21c39e58b0bb9c4840fc
Installing ruby-2.2.0...
BUILD FAILED (Ubuntu 14.04 using ruby-build 20141225-7-g4aeeac2)
Inspect or clean up the working tree at /tmp/ruby-build.20150105132503.8460
Results logged to /tmp/ruby-build.20150105132503.8460.log
Last 10 log lines:
make[1]: *** [ext/fiddle/all] Error 2
make[1]: *** Waiting for unfinished jobs....
installing default nkf libraries
installing default date_core libraries
linking shared-object date_core.so
make[2]: Leaving directory `/tmp/ruby-build.20150105132503.8460/ruby-2.2.0/ext/date'
linking shared-object nkf.so
make[2]: Leaving directory `/tmp/ruby-build.20150105132503.8460/ruby-2.2.0/ext/nkf'
make[1]: Leaving directory `/tmp/ruby-build.20150105132503.8460/ruby-2.2.0'
make: *** [build-ext] Error 2
</pre>
I have resolved this issue by installing following dependencies<br />
<pre class="rails" name="code">sudo apt-get install autoconf bison libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
</pre>
<b>References:</b><br />
<a href="https://github.com/sstephenson/ruby-build/wiki
">https://github.com/sstephenson/ruby-build/wiki
</a></div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com2tag:blogger.com,1999:blog-5615275573872642580.post-89831253594302747812014-05-25T11:41:00.001+05:302014-05-25T11:41:35.468+05:30How to: Override devise default routes for sign in and sign out<div dir="ltr" style="text-align: left;" trbidi="on">
In one of my application, I need to override default routes provided by Devise for better SEO.<br />
<br />
SEO expert asked me to change default url in such way,<br />
<i>"/users/sign_in" => "/sign-in"</i><br />
<i>"/users/sign_up" => "/sign-up"</i><br />
<br />
And I know, it is possible in devise. Devise is awesome authentication gem which provides lots of customization as per our app needs. In fact, every gem publisher should study the devise code for better understanding on how to provide api's for customization.<br />
<br />
So here is the full customization of default routes,<br />
<br />
<script src="https://gist.github.com/rahul100885/c5985bc8c49a9efc8fc6.js"></script>
<b>redirect section : </b><br />
On line 5 and 6, I wrote a redirection rule for SEO purpose and for demonstration over here. But best place is to place redirection rules in your web server, that is in nginx or apache.<br />
This only applies to you, if your app is already live and search engine has already indexed your sign in and sign out routes.<br />
<br />
<b>skip section :</b><br />
On line 10, I have skipped generation of default routes for session(sign_in) and registration(sign_up).<br />
<br />
<b>devise_scope block :</b><br />
In devise_scope block, we need to provide our own urls for sign_in and sign_out. So we need to provide url format with controller and action.<br />
Also, for each urls, we need to provide path helper using ":as", so that we can still use old path name, without code change. <br />
<br /></div>
Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-31793536337289649972014-05-06T12:07:00.001+05:302014-05-06T12:18:29.603+05:30Upgrading from Rails 4.0 to rails 4.1 - My experience <div dir="ltr" style="text-align: left;" trbidi="on">
<b>TL;DR: </b>I have recently upgraded one of my rails app from rails version 4.0 to 4.1 and collected steps over here.<br />
<br />
Before starting upgrade I went through following link and it is definitely worth to read those links,<br />
1. <a href="http://edgeguides.rubyonrails.org/4_1_release_notes.html" target="_blank">Rails 4.1 release notes</a><br />
2. <a href="http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-4-0-to-rails-4-1" target="_blank">Rails 4.1 upgrade steps</a><br />
<br />
These link almost covered every thing which we need to for rails 4.1 upgrade. Thanks to rails team.<br />
<br />
While upgrading you have to note that, your app might be using some gems which is not yet rails-4.1 compatible or might be it's dependent gem.<br />
In my case it was, "<a href="https://github.com/mhfs/sidekiq-failures/" target="_blank">sidekiq-failures</a>" which was not compatible with sidekiq-3.0.0 and sidekiq-3.0.0 was rails-4.1 compatible. So I have disabled "<a href="https://github.com/mhfs/sidekiq-failures/" target="_blank">sidekiq-failures</a>" for now. ( Author of gem is working on it and might be he has fixed it be the now ).<br />
<br />
Here are my steps for rails upgrade.<br />
<b>1. bundle update :</b><br />
Bundle update is our routine process, but still I have started with it. So that my stack is ready with all latest gems. You can use "bundle outdated" to check which of your gems are outdated and how much. If major update is happening with any gem then you must have to look into its release notes.<br />
<br />
<b>2. Rails 4.1 update and bundle update again :</b><br />
Then I have updated rails version first and then bundle update again. Along with this update I have referred <a href="http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-4-0-to-rails-4-1" target="_blank">rails upgrade steps guide</a> and followed steps which was applicable to my apps.<br />
<br />
Out of that important once are,<br />
1. <a href="http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#config-secrets-yml" target="_blank">Changes to config/secrets.yml</a><br />
2. <a href="http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#changes-to-test-helper" target="_blank">Changes to test helper</a><br />
3. <a href="http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#spring" target="_blank">Addition of spring gem</a><br />
<br />
These are important changes and you have to do it before proceeding.<br />
<br />
<b>3. Spec run and code fixes : </b><br />
Running test cases over here is very much important to quickly identify issue with code.<br />
Here are some of failing cases,<br />
<b>a. has_many with through relation :</b><br />
one of my relation was failing with wrong query<br />
relation was post has_many badges
<br />
<pre class="rails" name="code">has_many :badges, -> { order "badgings.id DESC" }, through: :badgings
</pre>
and failing query is,
<br />
<pre class="rails" name="code">"SELECT "badges".* FROM "badges" ORDER BY badgings.id DESC"
</pre>
So here I was ordering badges using through relation, which is indeed wrong, but I was surprised why it was working previously and not after upgrade. I tried to find cause but not able to find it.<br />
Please comment here, if you know the cause.<br />
<br />
For fixing I have changed above line to,
<br />
<pre class="rails" name="code">has_many :badges, -> { order "badges.id DESC" }, through: :badgings
</pre>
<b>b. Complex count quires :</b><br />
The Major changes, I did with count queries in all pagination. I have changed
<br />
<pre class="rails" name="code">@tags.all.count
</pre>
to
<br />
<pre class="rails" name="code">@tags.to_a.count
</pre>
Please see <a href="https://github.com/rails/rails/pull/10710">https://github.com/rails/rails/pull/10710</a><br />
<br />
<b>4. Removed <a href="http://edgeguides.rubyonrails.org/4_1_release_notes.html" target="_blank">mail_view</a> gem ( If you are using ): </b>
<br />
<div>
Now mail_view gem is part of rails 4.1. As, author of mail_view gem has integrated his gem into rails so there is very less change need to do.</div>
<div>
<div>
- remove mail_view routes mounting from routes </div>
<div>
- and search and replace MailView to ActionMailer::Preview</div>
</div>
<div>
<br /></div>
<div>
Apart from these steps, I have followed following steps which are only applicable if your are using sidekiq-3 or acts-as-taggable-on-3.1</div>
<div>
<b>1. For sidekiq :</b></div>
<div>
<div>
If you are using Sidekiq for back-grounding and Capistrano for deployment, then your Capistrano script will fail if you have upgraded to Sidekiq-3. Since in Sidekiq-3, <a href="https://github.com/mperham/sidekiq/wiki/Deployment" target="_blank">Capistrano integrated support has been removed</a>.</div>
<div>
To make Capistrano script to work, we need to use "capistrano-sidekiq" gem.</div>
<div>
<div>
- Just add "capistrano-sidekiq" gem to Gemfile</div>
<div>
- And replace "sidekiq/capistrano" to "capistrano/sidekiq" in Capfile.</div>
</div>
<div>
<a href="http://stackoverflow.com/questions/23240086/cap-deployment-is-failing-with-loaderror-cannot-load-such-file-sidekiq-capi/23240087#23240087">http://stackoverflow.com/questions/23240086/cap-deployment-is-failing-with-loaderror-cannot-load-such-file-sidekiq-capi/23240087#23240087</a></div>
<div>
<br /></div>
<div>
<b>2. For acts-as-taggable-on :</b></div>
<div>
If you have upgraded acts-as-taggable-on-3.1.1 then you need to run the following generator,
<br />
<pre class="rails" name="code">rake acts_as_taggable_on_engine:install:migrations
</pre>
<div>
Since acts-as-taggable-on has added some new columns in tagging system.</div>
</div>
<div>
<a href="http://stackoverflow.com/questions/23239578/after-upgrading-to-rails-4-1-acts-as-taggable-on-is-not-working">http://stackoverflow.com/questions/23239578/after-upgrading-to-rails-4-1-acts-as-taggable-on-is-not-working</a></div>
<div>
<br /></div>
<div>
<div>
And done. Now my app is working on rails 4.1 very smoothly. </div>
</div>
<div>
<br /></div>
<div style="font-weight: bold;">
<br /></div>
</div>
</div>
Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-11099114991052491452013-10-14T00:28:00.000+05:302013-10-14T00:28:04.359+05:30Testing Responsive web design with Rspec<div dir="ltr" style="text-align: left;" trbidi="on">
Recently I am working on an application where we have used <a href="http://foundation.zurb.com">zurb foundation</a> for responsive web design. We have separated all devices screen broadly into three categories as follows,<br />
<br />
1. small : Screen width upto 590.<br />
2. medium : Screen width upto 1025.<br />
3. large : Screen width uptp 1280. <br />
<br />
Very soon we will add new category,<br />
4. xlarge : above 1280+ ;)<br />
<br />
Now all things are fine, but until you didn't write acceptance test, you can't make sure that your design is working fine for all screen.<br />
<br />
Before taking responsive web design into consideration, we have already written feature specs using rspec + capybara (selenium).<br />
<br />
So here we want handy configuration which will not affect existing feature spec and should treat existing specs meant to be written for large screen.<br />
<br />
So here is, how I have added configuration for my rspec suite to target testing responsive design.
<br />
<script src="https://gist.github.com/rahul100885/6965813.js"></script>
<br />
<script src="https://gist.github.com/rahul100885/6965813.js"></script>
<br />
With above configuration, if you write any feature spec without :device_size then it will run that spec against 'large' screen. And if you want to write a spec for 'small' and 'medium' devices you can write by using metadata 'device_size => :small' or 'device_size => :medium'<br />
e.g.
<pre class="rails" name="code">
feature "XYZ" do
scenario "abc", :js => true do
# spec with default screen size i.e large
end
scenario "abc", :js => true, :device_size => :small do
# spec with small screen size
end
end
</pre>
With the help of 'config.include ScreenSize, :type => :feature' you can directly change screen size into example.<br />
e.g.
<pre class="rails" name="code">
feature "XYZ" do
scenario "abc", :js => true do
set_screen_size(:medium)
# spec with default screen size i.e large
end
end
</pre>
If you want to some special configuration based on device size you can do that using, <br />
<pre class="rails" name="code">
config.before(:each, :device_size => :small) do
# special configuration .........
end
</pre>
<b>TODO :</b><br />
I want to split a test suite into feature/small/*.rb for small devices, feature/large/*.rb for large devices and so on..
and apply specific metadata configuration based on type of suite.<br />
<br />
<b>References :</b><br />
<a href="http://www.blaulabs.de/2011/11/22/acceptance-testing-with-responsive-layouts">http://www.blaulabs.de/2011/11/22/acceptance-testing-with-responsive-layouts</a>
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-49872121612035191632013-09-22T23:59:00.000+05:302013-09-22T23:59:14.473+05:30Capybara wait for ajax call to finish<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="color: #222222; font-family: arial; font-size: small;">
<b>TL;DR:</b> Before capybara 2.0.0, wait_until method was available which can be used for wait for ajax call to finish. In capybara 2.0.0, wait_until method is removed as it is not needed and was creating confusion. Capybara automatically waits for elements to appear or disappear on the page. If you do something like find("#foo"), this will block until an element with id “foo” appears on the page, as will has_content?("bar"), click_link("baz") and most other things you can do with Capybara.</div>
<br />
Since today morning I was facing very strange issue with capybara feature spec. One of my spec was failing with following error.
<br />
spec:
<br />
<pre class="rails" name="code"> scenario "can create comment" do
user = FactoryGirl.create(:user, :email => "p@abc.com")
post = FactoryGirl.create(:published_post)
login(user)
visit post_path(post)
page.find('#comment_body').set("This is my comment")
keypress_script = "var e = $.Event('keypress', { keyCode: 13 }); $('#comment_body').trigger(e);"
page.execute_script(keypress_script)
page.should have_text("This is my comment")
page.should have_link('Reply')
page.should have_link('Edit')
page.should have_link('Destroy')
end
</pre>
<br />
<pre class="rails" name="code">
expected to find text "This is my comment" in "BROWSE CATEGORIES FORMATS MY PREGNANCY VOICES SERVICES POST TAGS MyText About Author1 — A brief write up about the author will come here. This will not exceed more than 250 characters. Give us your opinion. Discuss it with people like you. Javier Huel - This is my comment 0 likes | 0 replies LIKE | Reply | Edit | Destroy SIMILAR POSTS about us | our team | our vision | give feedback | privacy policy | terms of use | best viewed in | careers | site map © 1998–2013 ABC, Inc. All rights reserved."
# ./spec/features/commets_spec.rb:42:in `block (3 levels) in <top (required)>'
</pre>
<br />
Now in above error, I am clearly able to see that the text is present in page, but still it is not able to match it.
<br />
<br />
To quickly understand what is happening, I have used pry. On pry prompt, just verified expectation again and this time it is evaluated true.
<br />
<pre class="rails" name="code">
[1] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_2>)> page.should have_text("This is my comment")
=> true
</pre>
<br />
Means, here capybara was not waiting for ajax call to finish.
<br />
<br />
So I have googled for "capybara + wait for ajax call to finish" and found solution to use "wait_until" method.
<br />
<br />
When I have tried this method, I got into another error,
<pre class="rails" name="code">
Failure/Error: wait_until do
NoMethodError:
undefined method `wait_until' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2:0x000000055981c0>
# ./spec/features/commets_spec.rb:41:in `block (3 levels) in <top (required)>'
</pre>
While googled more, I found strong discussion of Jonas Nicklas and found that wait_until is removed from capybara 2.0.0 ;(.
<br />
<br />
Alternatively, I found how to implement "wait_until" back into capybara.
<br />
<br />
But in same discussion Jonas Nicklas has posted a link of his blog post where he has explained about why this decision was reached. Also he has mentioned how we can wait for ajax call to modify DOM.
<br />
<br />
So, my spec changed to,
<pre class="rails" name="code">
scenario "can create comment" do
user = FactoryGirl.create(:user, :email => "p@abc.com")
post = FactoryGirl.create(:published_post)
login(user)
visit post_path(post)
page.find('#comment_body').set("This is my comment")
keypress_script = "var e = $.Event('keypress', { keyCode: 13 }); $('#comment_body').trigger(e);"
page.execute_script(keypress_script)
page.should have_selector(".comment", :text => "This is my comment")
page.should have_link('Reply') # Subsequent call also passed due to have_selector
page.should have_link('Edit')
page.should have_link('Destroy')
end
</pre>
and which is passing. ;)
<br />
<br />
<b>References :</b>
<br />
<a target="_blank" href="https://groups.google.com/forum/#!topic/ruby-capybara/qQYWpQb9FzY">https://groups.google.com/forum/#!topic/ruby-capybara/qQYWpQb9FzY</a> <br />
<a target="_blank" href="http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara">http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara</a> <br />
<a target="_blank" href="https://gist.github.com/KevinTriplett/5087744">https://gist.github.com/KevinTriplett/5087744</a> <br />
</div>
Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com1tag:blogger.com,1999:blog-5615275573872642580.post-35678473498600579002013-05-06T12:47:00.000+05:302013-05-06T12:50:24.415+05:30Ubuntu 13.04 + XPS Dell + sound is not working Recently I have upgraded my Ubuntu OS from 12.10 to 13.04 on my Dell XPS.</br>
</br>
But suddenly I faced issue with my sound. I am not able to get sound form my machine.</br>
</br>
After googling, I found solution for Dell Vostro, but after some time I found for dell xps too. I tried solution on my Dell box and my sound is back.</br>
</br>
Here is the solution,
</br>
<pre class="rails" name="code">
sudo gedit /etc/modprobe.d/alsa-base.conf
</pre>
Add following line at the bottom of a file
<pre class="rails" name="code">
options snd-hda-intel model=dell-bios
</pre>
But don't forget to reboot your machine.
</br>
<b>References : </b></br>
<a href="http://askubuntu.com/questions/288503/vostro-3560-sound-is-not-working-after-upgrade-to-ubuntu-13-04">http://askubuntu.com/questions/288503/vostro-3560-sound-is-not-working-after-upgrade-to-ubuntu-13-04</a></br>
<a href="http://ubuntuforums.org/showthread.php?t=1457676">http://ubuntuforums.org/showthread.php?t=1457676</a>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-92187658776872729482012-09-22T13:29:00.000+05:302012-10-03T11:48:18.621+05:30Rails 4 - Transaction isolation level<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
After long time I am writing small post, as now a days not able manage a time or you can say I am just working ;)<br />
<br />
<b>TL;DR</b> - In Rails 4, <a href="http://jonathanleighton.com/" target="_blank">Jon Leighton</a> has added a support for specifying transaction isolation level. This transaction level we can pass when starting transaction(or you can say while calling transaction method)<br />
<br />
<b>Note :</b> This blog post is copied from <a href="https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253" target="_blank">Jon Leighton commits</a>, which he did in a rails repository<br />
<br />
Before continuing reading this post, it will be good if you read about Transaction Isolation over <a href="http://en.wikipedia.org/wiki/Isolation_(database_systems)" target="_blank">here</a>.<br />
<br />
Isolation is a property that defines how/when the changes made by one operation become visible to other concurrent operations. Isolation is one of the ACID (Atomicity, Consistency, Isolation, Durability) properties.<br />
<br />
Highlevel of Isolation does affect on Concurrency property of ACID, as it require to use locks or multiversion concurrency control.<br />
<br />
Anyways here is a documentation which <a href="http://jonathanleighton.com/" target="_blank">Jon Leighton</a> has added in rails trank.<br />
<br />
<pre style="border:1px solid #C5D5DD;background-color: #E6F1F6;padding: 8px 8px 0;" class="wordwrap">
If your database supports setting the isolation level for a transaction, you can set it like so:
Post.transaction(isolation: :serializable) do
# ...
end
Valid isolation levels are:
* `:read_uncommitted`
* `:read_committed`
* `:repeatable_read`
* `:serializable`
You should consult the documentation for your database to understand the semantics of these different levels:
* <a href="http://www.postgresql.org/docs/9.1/static/transaction-iso.html">http://www.postgresql.org/docs/9.1/static/transaction-iso.html</a>
* <a href="https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html">https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html</a>
An `ActiveRecord::TransactionIsolationError` will be raised if:
* The adapter does not support setting the isolation level
* You are joining an existing open transaction
* You are creating a nested (savepoint) transaction
The mysql, mysql2 and postgresql adapters support setting the transaction isolation level. However, support is disabled for mysql versions below 5, because they are affected by a bug (http://bugs.mysql.com/bug.php?id=39170) which means the isolation level gets persisted outside the transaction.
</pre>
<b>References :</b><br />
<a href="http://en.wikipedia.org/wiki/Isolation_(database_systems)">http://en.wikipedia.org/wiki/Isolation_(database_systems)</a><br />
<a href="http://www.postgresql.org/docs/9.1/static/transaction-iso.html">http://www.postgresql.org/docs/9.1/static/transaction-iso.html</a><br />
<a href="https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html">https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html</a><br />
<a href="https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253">https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253</a><br />
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-1854679630817996692012-07-01T19:10:00.001+05:302012-07-01T19:13:30.413+05:30bundle install + tar_input.rb:49:in `initialize': not in gzip format (Zlib::GzipFile::Error)<div dir="ltr" style="text-align: left;" trbidi="on">This is one of the pending post since 6 month, thought it might helpful to some people.<br />
<br />
Today on production server our system team found very strange issue with REE and bundler which lead production server was down for 20 min. This issue did not occur on test (Since on test and production have different version of REE)<br />
<br />
Issue is as follows,<br />
<script src="https://gist.github.com/3028436.js"> </script><br />
<br />
Issue was new to me, so I started digging into it using the almighty google.<br />
<br />
The solution which I found on net was not applicable since we couldn't afford a downtime.<br />
<br />
Issue is actually with ruby-enterprise-1.8.7-2010.02. Which is fixed in ruby-enterprise-1.8.7-2011.01 as described in release note.<br />
<br />
<a href="http://blog.phusion.nl/2011/02/12/ruby-enterprise-edition-1-8-7-2011-01-released/">http://blog.phusion.nl/2011/02/12/ruby-enterprise-edition-1-8-7-2011-01-released/</a><br />
<br />
But we don't have a time to upgrade REE at this point. So I digged into it and found temporary solution described here.<br />
<a href=" http://stackoverflow.com/questions/2494659/strange-bundler-error-tar-input-rb49in-initialize-not-in-gzip-format-zlib"><br />
http://stackoverflow.com/questions/2494659/strange-bundler-error-tar-input-rb49in-initialize-not-in-gzip-format-zlib</a><br />
<br />
Basically you have to clear you gem cache either you are use rvm or not. so I have simply deleted content from my gems folder<br />
like,<br />
<pre class="rails" name="code">sudo rm -rf /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/cache/
</pre><br />
And this worked !!!....</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-49541987418700888662012-02-12T23:23:00.000+05:302012-02-12T23:23:43.298+05:30Configure Repository In Redmine<div dir="ltr" style="text-align: left;" trbidi="on">
<p>
As Rubyist, most of us we use <a href="http://www.redmine.org">Redmine</a> for Project Management and <a href="http://git-scm.com">git</a> for source code management.
Written using the Ruby on Rails framework, it is cross-platform and cross-database. Redmine is open source and released under the terms of the GNU General Public License v2 (GPL).
</p>
<p>
Git is a free & open source, distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
</p>
<p>
Redmine provides many features out of that is SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs), which I going to explaing you in this blog post.
</p>
<p>
I am explaning this because, many time we do a code review for team members. Also some time we need to review a perticuler fix done for any bug. At that time it is very difficult to go through a git log.
</p>
<p>
So it will be great to use to redmine for this, were we can attach a code to feature or bug and even from git log to issue.
</p>
<p>
Redmine has this great feature,
<a href="http://www.redmine.org/projects/redmine/wiki/RedmineRepositories#Repository-user-mapping">http://www.redmine.org/projects/redmine/wiki/RedmineRepositories#Repository-user-mapping</a>
</p>
<p>
Now if we have already git server then, then their are two solution available,
<ol>
<li>Make git server to support http protocol</li>
<li>Replicate git server on Redmine server it self</li>
</ol>
</p>
<p>
both above option are very easy but issue in second option. Issue if you have git server which is runnning separately. Which happens in my case.
</p>
<p>
Our git server is only accessisble via git protocol like
<pre name="code" class="rails">
git clone user_name@repository_server:path_to_project.git
</pre>
</p>
<p>
Our git server is used by more than 30 developers were more than 13 repositories get accessed. So I don't want to distrub the development process. So I have decided to replicate git server on redmine.
</p>
<p>
<b>A. Replicate git server to be used by Redmine</b>
<ol>
<li>Login to your Redmine server from console</li>
<li>Clone the repository with following command</li>
</ol>
<pre name="code" class="rails">
# change to your respective user
$ su - name_of_user
# Create a folder to hold your repository
$ mkdir /any/path/to/create/repo
# change directory
$ cd /any/path/to/create/repo
# Make a bare clone of the repo
$ git clone --bare ssh://git@reposerver/usr/local/git_root/foo-project.git
# Switch to repository
$ cd foo-project.git
# add orignal repository in newly created repository for fetching changes done in orignal repository
$ git remote add origin ssh://git@reposerver/usr/local/git_root/foo-project.git
# Above command will feches commit from origanl repo
$ git fetch origin
$ git reset --soft refs/remotes/origin/master
#Make sure bypass the password prompt using ssh config for following command to work from crontab.
# Add the following to your crontab
*/10 * * * * cd /var/local/git_copies/foo-project.git && git fetch origin && git reset --soft refs/remotes/origin/master > /dev/null
</pre>
<p>
Using above command we have setuped a replica of git server on redmine server.
</p>
</p>
<p>
<b>B. Add project repository in Redmine</b>
<p>
Go to the redmine, select your project and add repository local path.
Goto => setting => repository
</p>
</p>
<p>
<b>C. Fetch commits into redmine</b>
</p>
When you first browse the repository, Redmine retrieves the description of all of the existing commits and stores them in the database.
</br>
This is done only once per repository but can take a very long time (or even time out) if your repository has hundreds of commits.
</p>
</p>
<p>
To avoid this, you can do it offline.
</br>
Run the following rake command on redmine server:
</p>
<p>
<pre name="code" class="rails">
$ ruby script/runner "Repository.fetch_changesets" -e production
</pre>
</p>
<p>
All commits will be retrieved in to the Redmine database.
</p>
<p>
Since Redmdine 0.9.x, you can use following link of your redmine to execute fetch_changesets for a specific project, or all.
<br>
<a href="http://redmine.example.com/sys/fetch_changesets">http://redmine.example.com/sys/fetch_changesets</a> (=> fetches changesets for all active projects)
</br>
<a href="http://redmine.example.com/sys/fetch_changesets?id=foo">http://redmine.example.com/sys/fetch_changesets?id=foo</a> (=> fetches changesets for project foo only)
</p>
<p>
Now we have sucessfully configured git reposiroty in Redmine.
</p>
<p>
Now you can use following link for linking revision and commits to issue and vice-varsa.
</br><a href="http://www.redmine.org/projects/redmine/wiki/RedmineTextFormatting">http://www.redmine.org/projects/redmine/wiki/RedmineTextFormatting</a>
</p>
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-8174706593608742822011-11-03T10:51:00.001+05:302011-11-03T10:52:46.552+05:30Passenger tuning for rails application<div dir="ltr" style="text-align: left;" trbidi="on">
Guys, it has been a long over due post. I have finished tuning passenger long back but caught up with Diwali celebration.<br />
<br />
Anyways generally I prefer simple and easily understandable configuration. So following configuration is as per my best knowledge and google findings. ;)<br />
<br />
I have verified my configuration using <a href="http://httpd.apache.org/docs/2.0/programs/ab.html">ab - Apache HTTP server benchmarking tool</a>. Also tried other tools such as Jmeter, httperf. I have also used passenger-memory-stats for finding rails instance size and passenger-status for finding number of request which are pending in global queue.<br />
<br />
I have started passenger tuning using <a href="http://modrails.com/documentation/Users%20guide%20Nginx.html">passenger nginx user guide</a>. You will also find passenger-apache guide.<br />
<br />
As I am using nginx, following configuration is with respect to nginx but same will applies for apache except some extra directives and syntax.<br />
<br />
After digging into passenger tuning, I realized that passenger well configured for production. But still Based on nginx-passenger user guide I have collected following list of directive, which we can configure according to our needs.<br />
<br />
<table class="gridtable">
<thead>
<tr>
<th scope="col" class="rounded-company">Directive</th>
<th scope="col" class="rounded-q1">Default Value </th>
<th scope="col" class="rounded-q2">Nginx Block</th>
<th scope="col" class="rounded-q3">Use</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerMaxPoolSize">passenger_max_pool_size <integer></a></td>
<td>6</td>
<td>http</td>
<td>Maximum instances on server</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerPoolIdleTime">passenger_pool_idle_time <integer></a></td>
<td>300 sec</td>
<td>http</td>
<td>instance idle time</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_passenger_max_instances_per_app_lt_integer_gt">passenger_max_instances_per_app <integer></a> </td>
<td>0</td>
<td>http</td>
<td>Maximum instances allowed to single app </td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerMinInstances">passenger_min_instances <integer></a></td>
<td>1</td>
<td>http, server, location, if</td>
<td>minimum number of application instances which are always active</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerPreStart">passenger_pre_start <url></a></td>
<td>-</td>
<td>http</td>
<td>Pre start application</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#PassengerUseGlobalQueue">passenger_use_global_queue <on|off></a></td>
<td>on</td>
<td>http, server, location, if</td>
<td>Turns the use of global queuing on or off</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_passenger_ignore_client_abort_lt_on_off_gt">passenger_ignore_client_abort <on|off></a></td>
<td>off</td>
<td>http, server, location, if</td>
<td>Ignore client aborts</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_rails_framework_spawner_idle_time_lt_integer_gt">rails_framework_spawner_idle_time <integer></a></td>
<td>1800 sec</td>
<td>http, server, location, if</td>
<td>FrameworkSpawner server idle time</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_rails_app_spawner_idle_time_lt_integer_gt">rails_app_spawner_idle_time <integer></a></td>
<td>600 sec</td>
<td>http, server, location, if</td>
<td>ApplicationSpawner server idle time </td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_passenger_log_level_lt_integer_gt">passenger_log_level <integer></a></td>
<td>0 (Can be 0, 1, 2, 3)</td>
<td>http</td>
<td>for how much information Passenger should write into error.log</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_passenger_debug_log_file_lt_filename_gt">passenger_debug_log_file <filename></a></td>
<td>error.log</td>
<td>http</td>
<td>allow to specify the file that debugging and error messages should be written</td>
</tr>
<tr>
<td><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_passenger_pass_header_lt_header_name_gt">passenger_pass_header <header name></a></td>
<td><br /></td>
<td>http, server, location, if</td>
<td>Used to pass headers</td>
</tr>
</tbody>
</table>
<br />
Almost all of these directive has default value which is good enough for an applications. But there are some directive which very important to configure depending on our application environment.<br />
<br />
<b>1. passenger_max_pool_size :</b><br />
The maximum number of Ruby on Rails or Rack application instances that may be simultaneously active. A larger number results in higher memory usage, but improved ability to handle concurrent HTTP clients.<br />
The value should be at least equal to the number of CPUs (or CPU cores) that you have. If your system has 2 GB of RAM, then we recommend a value of 30. If your system is a Virtual Private Server (VPS) and has about 256 MB RAM, and is also running other services such as MySQL, then we recommend a value of 2.<br />
I recomond you to find your application instance size using passenger-memory-stats and configure value of passenger_max_pool_size.<br />
<b>e.g.</b> If your application instance size is 300 MB and RAM size 2 GB then value of passenger_max_pool_size should be 4 because 1200 MB(4*300) will be used by application instance and remaning for other process.<br />
<br />
<b>2. passenger_max_instances_per_app :</b><br />
The maximum number of application instances that may be simultaneously active for a single application. This helps to make sure that a single application will not occupy all available slots in the application pool.<br />
This value must be less than passenger_max_pool_size. A value of 0 means that there is no limit placed on the number of instances a single application may use, i.e. only the global limit of passenger_max_pool_size will be enforced.<br />
<br />
<b>3. passenger_pre_start :</b><br />
By default, Phusion Passenger does not start any application instances until said web application is first accessed. The result is that the first visitor of said web application might experience a small delay as Phusion Passenger is starting the web application on demand. If that is undesirable, then this directive can be used to pre-started application instances during Nginx startup.<br />
This directive accepts the URL of the web application you want to pre-start. It may be specified any number of times.<br />
<pre name="code" class="rails">
passenger_pre_start http://foo.com/;
passenger_pre_start http://bar.com:3500/;
passenger_pre_start http://myblog.com/store;
</pre>
<h3>Let's get into live scenarios</h3><br />
<b>1. A server with multiple rails applications (Development and test server)</b><br />
I have a server with 16 GB of RAM and 8 core cpu, on which redmine(bug tracking system), test rails app and other developers app instances are running. Means you can say mutiple apps are running.<br />
According to passenger-memory-stats redmine is taking 300 MB and other rails app 500 MB. So I have kept following configuration<br />
<pre name="code" class="rails">
passenger_max_pool_size 16;
# arround 8 GB for rails application and remaning for other process
passenger_pool_idle_time 150;
# reduced idle time as multiple app are running
passenger_max_instances_per_app 8;
# since single app should not use whole pool size, but simuteniouly should handle mutiple requests
</pre>
<b>2. A server with single rails application (Production server)</b><br />
On my production enviroment we have 8 GB of RAM and 4 core cpu, on which only single rails application is running.<br />
As my rails application instance size is 500 MB, I have kept following configuration on production<br />
<pre name="code" class="rails">
passenger_max_pool_size 10;
# arround 5 GB for rails application and remaning for other process
passenger_pool_idle_time 600;
# Increased as it is production
passenger_min_instances 2;
# atlease two instances should in memory at any time
passenger_pre_start http://myprodapp.com/;
# pre start my instance at the time of nginx start instade on first request
</pre>
For testing whether required instances are forked or not use ab (Apache benchmark) as described above.<br />
<br />
<b>Reference :</b> <a href="http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/">http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/ </a>
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-41444994802466234682011-10-14T14:21:00.000+05:302011-10-20T12:22:57.146+05:30Simple nginx tuning for rails application on production server<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="margin-bottom: 0in;">
Recently I was working on tuning my
production environment for better performance. In production server
mainly three things makes a difference to the web application,</div>
<ol>
<li><div style="margin-bottom: 0in;">
REE-GC Tuning</div>
</li>
<li><div style="margin-bottom: 0in;">
Nginx Tuning
</div>
</li>
<li><div style="margin-bottom: 0in;">
Passenger Tuning</div>
</li>
</ol>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
As I have already done <a href="http://blog.railsupgrade.com/2011/02/garbage-collector-performance-tuning.html">REE-GC tuning</a>
in previous articles, so lets discuss on Nginx tuning. Passenger
tuning will be get covered in subsequent articles.</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
In Nginx there are many ways to boost
your application performance, but I would like to share few important
tweaks.</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
To validate performance improvement,
you can use <a href="http://code.google.com/speed/page-speed/">page-speed</a>
or <a href="http://developer.yahoo.com/yslow/">Yslow</a>
</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
Before doing these tweaks on my rails
application, yslow and page-speed score was around 25-35/100. After
doing these tweaks it increased to 90-96/100</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
To get 100/100 we have to write a good
code-design not best code-design ;). In our application the performance dip is due to not using CSS sprite.
</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
<br />
<b>A. Enable Gzip :</b></div>
<div style="margin-bottom: 0in;">
Gzip helps to compress and decompress the data
on-the-fly between browser and server. Nginx has
<a href="http://wiki.nginx.org/HttpGzipModule">HttpGzipModule</a> for same.</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
Add following lines into to http block
nginx.conf</div>
<pre name="code" class="rails">
gzip on;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
#gzip_proxied any;
#gzip_buffers 128 128k;
#gzip_min_length 1100;
</pre>
<div style="margin-bottom: 0in;">
Depending on your need you can set the
above commented directives.</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<div style="margin-bottom: 0in;">
<br />
<b>B. Enable caching :</b></div>
<div style="margin-bottom: 0in;">
Setting an expiry date or a maximum
age in the HTTP headers for static resources instructs the browser to
load previously downloaded resources from local disk rather than over
the network.</div>
<div style="margin-bottom: 0in;">
<br />Add following lines into to server
block nginx.conf</div>
<pre name="code" class="rails">
location ~* \.(ico|css|js|gif|jpe?g|png|swf)(\?[0-9]+)?$ {
expires max;
break;
}
</pre>
<br />
<div style="margin-bottom: 0in;">
<b>C. Minify JavaScript :</b>
</div>
<div style="margin-bottom: 0in;">
Compacting JavaScript code can save
many bytes of data and speed up downloading, parsing, and execution
time.</div>
<div style="margin-bottom: 0in;">
For this you can use any third party
tools or gems like Jammit,asset_packager to minify your JavaScript files.
Rails 3 has built in
support.</div>
<div style="margin-bottom: 0in;">
<br />
</div>
<b>Sample nginx.conf : </b>
<script src="https://gist.github.com/1286563.js"> </script>
<div style="margin-bottom: 0in;">
Apart from this you can use <b>multiple assets
server for static resources</b>, which will be covered in subsequent
articles.</div>
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com1tag:blogger.com,1999:blog-5615275573872642580.post-57045807373409598932011-08-23T12:54:00.010+05:302011-08-25T13:31:56.176+05:30Install Redis server on Ubuntu maunally as service<p>This post is all about installing redis server manually on Ubuntu system and then setup it as a service.</p><p></p><p>For this post I have originally referred a blog post of denofubiquity.</p><p></p><p>By default Ubuntu provides redis server installation by </p><pre name="code" class="rails">sudo apt-get install redis-server
</pre><p> </p><p>And you done with the installation of redis server.</p><p></p><p>But if you want to install latest version of redis server, then you can go through the rest of post. </p><p></p><pre name="code" class="rails">wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz
# You can specify a link of redis-server which you want to install
tar -zxf redis-2.2.12.tar.gz
cd redis-2.2.12
make
sudo make install
</pre><p></p><p>Now setup a redis.conf. I have copied a redis.conf from default installation of redis-server which I have used. If you want to install redis-server for your production machine you may refer a redis.conf from denofubiquity's post</p><p></p><pre name="code" class="rails">wget https://raw.github.com/gist/1164482/77e4ecf14ffac42b0e987e7ffe16cb757d734ff9/redis.conf
sudo mkdir /etc/redis
sudo mv redis.conf /etc/redis/redis.conf
</pre>Copy redis-server startup scripts.<br />
<pre name="code" class="rails">wget https://raw.github.com/gist/1164503/d1bc2cc6782b943d9b28aa93fc7038f4ae5a905f/redis-server
sudo mv redis-server /etc/init.d/redis-server
sudo chmod +x /etc/init.d/redis-server
</pre><pre name="code" class="rails">sudo useradd redis
sudo mkdir -p /var/lib/redis
sudo mkdir -p /var/log/redis
sudo chown redis.redis /var/lib/redis
sudo chown redis.redis /var/log/redis
</pre>Mark redis server as startup services.<br />
<pre name="code" class="rails">sudo update-rc.d redis-server defaults
</pre>Start your redis server.<br />
<pre name="code" class="rails">sudo /etc/init.d/redis-server start
</pre><p></p><p><strong>Note :</strong></p><p>You can customise your redis configuration as per your requirements.<br />
Like from Redis 2.2, it supports unix socket, so you can use it if required.<br />
- Specify socket in redis.conf using this line<br />
<i>unixsocket /tmp/redis.sock</i><br />
- Tell Redis.new() to read it as required. like<br />
<i>Redis.new(:path => "/tmp/redis.sock")</i><br />
<br />
Also you can customise memory configuration in your redis.conf.<br />
</p><p><strong>Reference :</strong></p><p><a href="http://www.denofubiquity.com/nosql/412">http://www.denofubiquity.com/nosql/412</a></p>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-2967219592130435472011-08-17T17:56:00.000+05:302011-08-17T17:56:52.197+05:30Nginx rewrite non-www url to www<p>One of my project facing issue with non-www url. At Browser side we are calling multiple services from different domain and same time we are sharing same cookies for calling services from our website. But it was giving authentication failure for our services.</p><p><strong>Issue:</strong></p><p>We have embedded zimbra collaboration suite into our rails application. Once user logged into our application, he will automatically gets Single signed into zimbra collaboration suite. We ware showing zimbra UI in separate iframe on web page.</p><p>Zimbra has nice feature to extend their own functionality using zimlet.</p><p>Zimlet is simply JavaScript code which runs on client side(On Browser).</p><p>Using the power of zimlet we want to access the services of our own application, where we ware sharing cookies which already got created for portal on browser side when user signed in.</p><p>Every thing was working fine on production. But some time some users were facing issue of authentication failure for zimlet functionality, even though they have signed in into rails application.</p><p>After digging into issue, found that some users accessing the application using without www. i.e "https://abcrails.com", and zimlet was trying to access a rails application using "https://www.abcrails.com" where authentication is failing. As cookies ware created for "https://abcrails.com" and not for "https://www.abcrails.com"</p><p>For this I have only one solution depending on my requirements, is force non-www url to www.</p><p><strong>So following nginx configuration is for:</strong></p><p>1. Force http reuest to https</p><p>2. Force non-www url to www</p><p></p><script src="https://gist.github.com/1151109.js"> </script>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-88048764549469090182011-08-15T02:42:00.001+05:302011-08-15T10:32:05.845+05:30Replace DelayedJob with Resque<h3>Background task in Ruby on Rails</h3><p>One of our task of migrating background task from Delayed_job server to the Resque server. But I have kept this task with low priority in my task list queue. </p><p>But since last week, our IT team is facing an issue with Delayed_job server. Our delayed_job server is getting crashed 20 times in 24 hours.</p><p>I havn't done the root cause analysis. but I have decided to take this an opportunity to replace delayed_job to resque server on high priority.</p><p>Is is not mean that Resque is better than Delayed_job. They have their own features. The working functionality of both server is same.</p><p>As Resque is best fitting in our requirements I have choose Resque in place of Delayed_job.</p><p>Also our IT team don't have any way or clue get the list of background tasks which are completed, which are pending and which are currently in process.</p><h4>Why Resque server:</h4><p>Well following info is sufficient from page <a href="https://github.com/defunkt/resque" title="https://github.com/defunkt/resque" target="_blank">https://github.com/defunkt/resque</a></p><p><em>Resque vs DelayedJob</em></p><p>How does Resque compare to DelayedJob, and why would you choose one over the other?</p><ul><li> Resque supports multiple queues</li>
<li> DelayedJob supports finer grained priorities</li>
<li> Resque workers are resilient to memory leaks / bloat</li>
<li> DelayedJob workers are extremely simple and easy to modify</li>
<li> Resque requires Redis</li>
<li> DelayedJob requires ActiveRecord</li>
<li> Resque can only place JSONable Ruby objects on a queue as arguments</li>
<li> DelayedJob can place any Ruby object on its queue as arguments</li>
<li> Resque includes a Sinatra app for monitoring what's going on</li>
<li> DelayedJob can be queried from within your Rails app if you want to add an interface</li>
</ul><p>If you're doing Rails development, you already have a database and ActiveRecord. DelayedJob is super easy to setup and works great. GitHub used it for many months to process almost 200 million jobs.</p><p>Choose Resque if:</p><ul><li> You need multiple queues</li>
<li> You don't care / dislike numeric priorities</li>
<li> You don't need to persist every Ruby object ever</li>
<li> You have potentially huge queues</li>
<li> You want to see what's going on</li>
<li> You expect a lot of failure / chaos</li>
<li> You can setup Redis</li>
<li> You're not running short on RAM</li>
</ul><p>Choose DelayedJob if:</p><ul><li> You like numeric priorities</li>
<li> You're not doing a gigantic amount of jobs each day</li>
<li> Your queue stays small and nimble</li>
<li> There is not a lot failure / chaos</li>
<li> You want to easily throw anything on the queue</li>
<li> You don't want to setup Redis</li>
</ul><p>In no way is Resque a "better" DelayedJob, so make sure you pick the tool that's best for your app.</p><h3><u>Action:</u></h3><p>This task is done for, quick solution to the production issue. So you might also use it, if you have same issue.</p><p>This task I have done on one of our project which is running on rails 2.3.5 with REE 1.8.7. But it will work same for rails 3 also.</p><p>Before diving into migration, I highly encourage you to checkout <a href="http://railscasts.com/episodes/171-delayed-job" title="RAILSCASTS-171 (Delayed-job)" target="_blank">railscasts 171(delayed_job)</a> and <a href="http://railscasts.com/episodes/271-resque" title="RAILSCASTS-271(Resque)" target="_blank">RAILSCASTS-271(Resque)</a>.</p><p><strong>1. Install Redis server</strong></p><p>It is dependency for resque server. Like Delayed_jobs uses database(delayed_jobs table), Resque uses Redis server.</p><p>I am using ubuntu so,</p><p>> sudo apt-get install redis-server</p><p>If you want to install latest version of the Redis you can install manually.</p><p><strong>2. Install resque gem</strong></p><p>If you are using bundler mention it in Gemfile or in your config/environment.rb depending on your application.</p><p><strong>3. Load Resque server tasks</strong></p><p>Add a file called lib/tasks/resque.rake</p><pre name="code" class="rails"># loads all rake task of resque
require 'resque/tasks'
# following statement is required only if your background task needs rails enviroment else skip it
task "resque:setup" => :environment
</pre><br />
<p><strong>4. Replace your Delayed_job code with Resque</strong></p><p>A.</p><p>Find a places in code where you or your developers has been used delayed_jobs.</p><p>For this you can simply find a line "send_later" or "Delayed::Job.enqueue" in your code.</p><p>Use your development IDE or use grep tool from command line</p><p>> cd your_project</p><p>> grep -rn "send_later" .</p><p>and</p><p>> grep -rn "Delayed::Job.enqueue" .</p><p>B.</p><p>From the above result you will able to find location where delayed_job is used.</p><p>So if your are using SomeModel.send_later(function_name, parameter1, parameter2, ..., parameter n)</p><p>Replace a line like this</p><pre name="code" class="rails">#SomeModel.send_later(function_name, parameter1, parameter2, ..., parameter n)
Resque.enqueue(NameOfModelOrClass, parameter1, parameter2, ..., parameter n)
</pre><p>Name of NameOfModelOrClass can be define from the following step</p><p>Either use one of the following </p><p>1. Modify respective model</p><p>Add following line into the model,</p><pre name="code" class="rails">@queue = :name_of_queue
</pre><p>Name of the queue can be any thing whatever you want. You can also logically separate background task by using queue name.</p><p>Mofify function_name in such way,</p><pre name="code" class="rails">def self.function_name(parameter1, parameter2, ..., parameter n)
{
# Defination of a function
}
</pre><p>to,</p><pre name="code" class="rails">#def self.function_name(parameter1, parameter2, ..., parameter n)
def self.perform(parameter1, parameter2, ..., parameter n)
{
# Defination of a function
}
</pre><p>2. Separate code from model which I have preferred.</p><p>Define class in lib folder(any location you want)</p><pre name="code" class="rails">Class FileImportWorker
{
@queue = :name_of_the_queue
def self.perform()
{
# cut the defination of the function_name and paste here
}
}
</pre><p>Pass this class name to Resque.enqueue method.</p><p>C.</p><p>if you are using Delayed::Job.enqueue(ClassOfJob.new(parameter1, parameter2, ..., parameter n))</p><pre name="code" class="rails">#Delayed::Job.enqueue(ClassOfJob.new(parameter1, parameter2, ..., parameter n))
Resque.enqueue(ClassOfJob, parameter1, parameter2, ..., parameter n)
</pre><p>e.g</p><pre name="code" class="rails">class NewsletterJob < Struct.new(:text, :emails)
def perform
emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
end
end
</pre>
<pre name="code" class="rails">Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&:email))
</pre><p>to,</p><pre name="code" class="rails">class NewsletterJob
@queue = :name_of_the_queue
def self.perform(text, emails)
emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
end
end
</pre><pre name="code" class="rails">Resque.enqueue(NewsletterJob, 'lorem ipsum...', Customers.find(:all).collect(&:email))
</pre><p><strong>5. Now start your Resque server,</strong></p><p>You can start server using a following command.</p><p>rake resque:work QUEUE=* COUNT=1</p><p>QUEUE=* : specify on which queue to work. * for all Queue</p><p>COUNT=1 : Number of worker process</p><p><strong>6. Access to queue</strong></p><p>Now you can run your code and can have look of pending and in-progress tasks. For this run the following command,</p><p>resque-web</p><p>It will start resque web interface on port 5678</p><p>http://localhost:5678</p><h3><u>Bonus Point:</u></h3><p><strong>1. Mount Reqsue web interface server into your application</strong></p><p>Instead of accessing resque web interface using localhost:5478, you can mount web interface into your application.</p><p>Add the following line into your config/routes.rb</p><pre name="code" class="rails">mount Resque::Server, :at => "/resque"
</pre><p>Now, access via http://your_server/resque</p><p>Also, you can provide basic authentication for it,</p><p>add a file called config/initializers/resque_auth.rb with following code,</p><pre name="code" class="rails">Resque::Server.use(Rack::Auth::Basic) do |user, password|
password == "secret"
end
</pre><p><strong>2. You can club background tasks (which we have defined in lib folder) into single folder</strong></p><p>As done in rails cast you can add a folder app/workers, and keep your all tasks file in it.</p><p>or </p><p>Which I done by adding folder lib/workers</p><p>Only you need to load this folder into your application,</p><p>In rails 2,</p><p>Add file config/initializers/load_workers.rb with following code.</p><pre name="code" class="rails">Dir["#{RAILS_ROOT}/lib/workers/*.rb"].each { |f| require(f) }
</pre><p>In rails 3,</p><p>add following line in application.rb,</p><pre name="code" class="rails">config.autoload_paths += %W(#{config.root}/lib/workers)
</pre><h3><u>Troubleshooting:</u></h3><p><strong>1. Resque database connection issue</strong></p><p>We are using postgresql in our portal but found that when I pushed my code on testing server where we are using same configuration which we have for our production ( We have configured Nginx + Passenger + REE for same), resque was not working. </p><p>After looking into resque-web interface found following error,</p><p>PGError: server closed the connection unexpectedly</p><p>Which I solved by adding following code into /lib/tasks/resque.rake</p><pre name="code" class="rails">task "resque:setup" => :environment do
ENV['QUEUE'] = '*'
Resque.after_fork do |job|
ActiveRecord::Base.establish_connection
end
end
desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"
</pre><p>You can find this solution in following URL.</p><a href="http://railscasts.com/episodes/271-resque" title="RAILSCASTS-271(Resque)" target="_blank">RAILSCASTS-271(Resque)</a>
<p><a href="http://stackoverflow.com/questions/2611747/rails-resque-workers-fail-with-pgerror-server-closed-the-connection-unexpectedly" title="http://stackoverflow.com/questions/2611747/rails-resque-workers-fail-with-pgerror-server-closed-the-connection-unexpectedly" target="_blank">http://stackoverflow.com/questions/2611747/rails-resque-workers-fail-with-pgerror-server-closed-the-connection-unexpectedly</a></p><p>I didn't find time to do root cause analysis for this issue, but I thing this is due to passenger as it was working well on my development machine in production mode.</p><p><strong>2. Sequence issue</strong></p><p>Exact error I forgot but I have faced a sequence related error. Solution was to not to pass a complex object in call Resque.enqueue, like ActiveRecord, File data etc. </p><p><strong>3. undefined method `******' for #Hash:000</strong></p><p>This is due to, if your are storing complex object(ActiveRecord) in resque. Resque uses Redis server which is key-value store, which returns object in hash. </p><p>So tackle this simple pass object-id as parameter and in background processing code extract the original object again using ID.</p>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-2585844916382203342011-05-28T01:17:00.002+05:302011-08-15T00:53:29.986+05:30Convert string to a class/modelThis post is related to how to convert string to class ( model ). I came across this situation while migrating one of my organization's project on rails 3.<br />
<br />
Many times we came across a situation where we need to convert a string to respective class or model. So that we can call methods on it. Generally to handle this situation new rails developers use case statement like this,<br />
<br />
<pre name="code" class="ruby">case class_name_string
when 'Account'
object = Account.find(id)
when 'Contact'
object = Contact.find(id)
when 'Opportunity'
object = Opportunity.find(id)
when 'Campaign'
object = Campaign.find(id)
when 'Model1'
object = Model1.find(id)
when 'Model2'
object = Model2.find(id)
:
:
:
:
when 'Modeln'
object = Modeln.find(id])
end
</pre><br />
This can be actually done pretty easily by using <b>constantize</b> in only one line<br />
<br />
<pre name="code" class="ruby">class_name_string.constantize.find(id)</pre>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-22438574117002660242011-05-22T18:42:00.003+05:302011-05-24T14:27:40.548+05:30Touch pad is not working on Ubuntu 11.04Following is blog post with respect to the problem which I faced on my dell xps laptop with Ubuntu 11.04. My mouse pad(Touch pad) was not working after login screen.<br />
<br />
After some googling I found forum articles which describing same problem. Those peoples have different version of Ubuntu with different manufactures of laptop.<br />
<br />
But I didn't found an exact cause of this issue. One of the person from the forum was saying, this is might be due to use of mobile broadband network.<br />
<br />
Might be this is the cause because, I am also using mobile broadband on my laptop where issue is occurring. But at the same time in my company I am using Ubuntu 11.04 on my development machine with wired Internet but I never faced this issue.<br />
<br />
Anyways following is the solution,<br />
Execute following command on terminal<br />
<code><br />
gconftool-2 --set --type boolean /desktop/gnome/peripherals/touchpad/touchpad_enabled true</code><br />
<br />
<b>Reference:</b><br />
<a href="https://help.ubuntu.com/community/SynapticsTouchpad"><br />
https://help.ubuntu.com/community/SynapticsTouchpad</a><br />
<a href="http://ubuntuforums.org/showthread.php?t=1658103">http://ubuntuforums.org/showthread.php?t=1658103</a>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-78578723539587255532011-04-15T11:26:00.008+05:302011-04-15T11:40:11.695+05:30Configure Rack-bug for rails 3<div dir="ltr" style="text-align: left;" trbidi="on"><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">While migrating one of my rails application on rails 3, I thought of using rack-bug simultaneously for improving performance.</span><br />
<div style="text-align: left;"><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Following are the steps which I used for configuring <a href="http://rack-bug%20/%20lib%20/%20rack%20/%20bug%20/%20panels%20/%20templates_panel%20/%20actionview_extension.rb">rack-bug</a> for rails 3 (3.0.6).</span><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"></span><b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">1. Install rack-bug (branch rails3) as plugin</span></b><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> cd vendor/plugins</span></i><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> git clone -b rails3 https://github.com/brynary/rack-bug.git</span></i><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></i><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">If you want to you it as gem then add following line into Gemfile</span><br />
<span class="Apple-style-span" style="font-family: monospace; white-space: pre;"><i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> gem 'rack-bug', :git => 'https://github.com/brynary/rack-bug.git', :branch => 'rails3'</span></i></span><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">2. Replace the code from file actionview_extension.rb</span></b><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><b></b>which is avilable in vendor/plugins/rack-bug/lib/rack/bug/panels/templates_panel/ as specified in <a href="https://github.com/brynary/rack-bug/issues/17">bug</a> of rack_bug repository</span><br />
<span class="Apple-style-span" style="font-family: monospace; white-space: pre;"><i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></i></span><br />
<span class="Apple-style-span" style="font-family: monospace; white-space: pre;"><i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">if defined?(ActionView) && defined?(ActionView::Template)</span></i></span><br />
<pre><code><i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> ActionView::Template.class_eval do
def render_with_rack_bug(*args, &block)
Rack::Bug::TemplatesPanel.record(virtual_path) do
render_without_rack_bug(*args, &block)
end
end
alias_method_chain :render, :rack_bug
end
end</span></i></code></pre><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">If you are using gem override the specified file in some way</span><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">3. Add following lines into your config.ru</span></b><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> require 'rack/bug'</span></i><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> use Rack::Bug, :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring"</span></i><br />
<i><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> run myapp</span></i><br />
<span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">4. Start your server and access the URL http://your_app/__rack_bug__/bookmarklet.html</span></b><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> and enter the password.</span></b><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixWnL3hOD_DSY6eLnO_SnTtQBhR_wAb4-KFdMSI_Ee3_Uf86awFFQ-B-saEha6JTOlOQC17lyojIenO_35-7UqaQ6osLjxcSqIb0bM6DyWJNVpZ_c3A8NNEOIkLm5lLoeAJs4ru-O_BXhy/s1600/rack-bug_rails3_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixWnL3hOD_DSY6eLnO_SnTtQBhR_wAb4-KFdMSI_Ee3_Uf86awFFQ-B-saEha6JTOlOQC17lyojIenO_35-7UqaQ6osLjxcSqIb0bM6DyWJNVpZ_c3A8NNEOIkLm5lLoeAJs4ru-O_BXhy/s320/rack-bug_rails3_1.png" width="320" /></a></div><b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3SuCdmwI4YW_V9Kt4yt-e-MElhQDZw3ToUnoEPrSV9Dm-KJ0vslAFkwZss12ErvGPbcvEvq6CpFjz7cOywLnffP5lRXGjL5DgEs5lqDoPa27lPt7GiyJMMEXq31TWIoix78t0S5v53mK6/s1600/rack-bug_rails3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3SuCdmwI4YW_V9Kt4yt-e-MElhQDZw3ToUnoEPrSV9Dm-KJ0vslAFkwZss12ErvGPbcvEvq6CpFjz7cOywLnffP5lRXGjL5DgEs5lqDoPa27lPt7GiyJMMEXq31TWIoix78t0S5v53mK6/s320/rack-bug_rails3.png" width="320" /></a></div><b><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></b></div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-75772139303081755742011-03-17T12:17:00.004+05:302011-03-24T00:56:08.675+05:30Ruby Version Manager with Gemset - ree installation<div dir="ltr" style="text-align: left;" trbidi="on"><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"></span><br />
<div class="wiki"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Recently I had given a session on Ruby version manager(RVM) with gemset, explained some of the important and useful bonus points which makes our life easier.</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">The reason behind this session being the need for our team to work on multiple projects and manage them efficiently, which run on different version of Rails. We are evaluating different version of ruby, like Ruby Enterprise edition, Ruby 1.9.2, Ruby 1.8.7.</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"></span><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">I have posted my <a href="http://www.slideshare.net/rahul100885/ruby-version-manager">presentation on slideshare</a>. You can download from there.</span><br />
<div style="width:425px" id="__ss_7260485"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/rahul100885/ruby-version-manager" title="Ruby version manager">Ruby version manager</a></strong> <object id="__sse7260485" width="425" height="355"> <param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rubyversionmanager-110314112751-phpapp02&stripped_title=ruby-version-manager&userName=rahul100885" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7260485" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rubyversionmanager-110314112751-phpapp02&stripped_title=ruby-version-manager&userName=rahul100885" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed> </object> <div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/rahul100885">Rahul Chaudhari</a> </div></div><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"></span><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Now, I would like to discuss a problem which my colleagues has faced while installing Ruby enterprise edition under RVM.</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><b>A. While they using a command,</b></span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">rvm install ree
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">They have got following error,</span><br />
<code><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span></code><br />
<code><i><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">ERROR: Error running './installer -a /home/usera/.rvm/rubies/ree-1.8.7-2011.03 --dont-install-useful-gems ', please read /home/usera/.rvm/log/ree-1.8.7-2011.03/install.log<br />
ERROR: There has been an error while trying to run the ree installer. Halting the installation.</span></i></code><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">So I have investigated about this error and I found that, some of the dependecy are met for ree installation.</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">This dependency I found using, installing ree manually under rvm,</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Go to ree source folder, where ree source code is located</span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">cd ~/.rvm/src/ree-1.8.7-2010.02
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Then copy the command from above error, which is</span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">./installer -a /home/usera/.rvm/rubies/ree-1.8.7-2011.03 --dont-install-useful-gems
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">After running above command, it will shows why ree installation failed.</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">On my colleague's machine, it is shows package <strong>libreadline5-dev</strong> is not installed</span><br />
<br />
<div class="wiki"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">So,</span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">sudo apt-get install libreadline5-dev
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Then install the dependeny that ree asked, and then install ree again</span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">rvm install ree
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><b>B. Also one of my colleague faced following issue, while starting server using ruby script/server</b></span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<code><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><i>/home/usera/.rvm/gems/ree-1.8.7-2011.03@livia_portal/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:55: uninitialized constant ActiveSupport:ependencies::Mutex (NameError)<br />
from /home/usera/.rvm/gems/ree-1.8.7-2011.03@livia_portal/gems/activesupport-2.3.5/lib/active_support.rb:56:in `require'<br />
from /home/usera/.rvm/gems/ree-1.8.7-2011.03@livia_portal/gems/activesupport-2.3.5/lib/active_support.rb:56<br />
from /home/usera/.rvm/gems/ree-1.8.7-2011.03@livia_portal/gems/rails-2.3.5/lib/commands/server.rb:1:in `require'<br />
from /home/usera/.rvm/gems/ree-1.8.7-2011.03@livia_portal/gems/rails-2.3.5/lib/commands/server.rb:1<br />
from script/server:3:in `require'<br />
from script/server:3</i></span></code><br />
<code><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span></code><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">After investing I found that, <a class="external" href="http://stackoverflow.com/questions/5176782/uninitialized-constant-activesupportdependenciesmutex-nameerror" style="background-image: url(http://projectpath.liviatech.com/images/external.png); background-position: 0% 60%; padding-left: 12px; text-decoration: none;">latest version of gem is conflicting with old versions of rails</a> (Rails-2.3.5 and gem 1.6.2).</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">So we have added following line into config/boot.rb</span><br />
<pre style="background-color: #fafafa; border-bottom: rgb(218,218,218) 1px solid; border-left: rgb(218,218,218) 1px solid; border-right: rgb(218,218,218) 1px solid; border-top: rgb(218,218,218) 1px solid; margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">require 'thread'
</span></pre><span class="Apple-style-span" style="font-family: Times, "Times New Roman", serif;">Which resolved the above issue.</span><br />
<div><br />
</div></div><div class="attachments" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px; margin-top: 12px;"></div></div><div id="wiki_add_attachment"></div></div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-75731740703614983482011-02-17T16:54:00.000+05:302011-02-17T16:54:45.505+05:30Zimbra authentication preauth in Ruby<div dir="ltr" style="text-align: left;" trbidi="on"><br />
In one of our project, we have integrated Zimbra Collabration Server. It’s an email and calendar server plus much more; think about it like a next-generation Microsoft Exchange server. In addition to email and calendar, it provides document storage and editing, instant messaging, and simplified administrative controls all in an award winning webmail user interface built with the latest AJAX web technology. ZCS also provides mobility and syncs to desktop client applications; the server is deployed on commodity Linux and Mac server hardware.<br />
<br />
Previosuly it was part of Yahoo, now it is part of Vmware.<br />
<br />
Zimbra provides two types of authentication mode for single sign on,<br />
1. URL based<br />
2. SOAP based<br />
<br />
The concept behind this is same is to generate pre authentication token called preauth.<br />
<br />
As we have integrated into ruby on rails application, I have wrote a code for generate preauth.<br />
Following is link for same.<br />
<br />
<a href="http://wiki.zimbra.com/wiki/Preauth#Sample_Ruby_code_for_computing_the_preauth_value">http://wiki.zimbra.com/wiki/Preauth#Sample_Ruby_code_for_computing_the_preauth_value</a><br />
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-66546928427186024962011-02-16T11:33:00.003+05:302011-03-02T21:29:32.445+05:30Uninstall all the gems<div dir="ltr" style="text-align: left;" trbidi="on"><span class="Apple-style-span" style="color: #484848; font-family: Verdana,sans-serif; font-size: 12px;"></span><br />
Many time a rails developer have an situation where they want to uninstall all gems which are installed.<br />
Here we can take an advantage of pipelining output from one command to other command.<br />
<pre style="background-color: #fafafa; border: 1px solid rgb(218, 218, 218); margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 2px 0px; width: auto;">gem clean
</pre>This command will remove multiple versions of gems and will keep only higher version of gem.<br />
<pre style="background-color: #fafafa; border: 1px solid rgb(218, 218, 218); margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 2px 0px; width: auto;">gem list --no-version | xargs gem uninstall
</pre>Here we are using pipelining, where command first will list all gems with no version, and second command will take it for consume.<br />
<br />
Extra :<br />
<br />
If you need to exclude some gem from being uninstall, use following command,<br />
<pre style="background-color: #fafafa; border: 1px solid rgb(218, 218, 218); margin: 1em 1em 1em 1.6em; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 2px 0px; width: auto;">gem list --no-version | grep -v "rake" | xargs rvmsudo gem uninstall</pre></div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-18476599938968878532011-02-13T23:51:00.000+05:302011-02-13T23:51:47.413+05:30Monitor Your Rails/Passenger App with Munin<div dir="ltr" style="text-align: left;" trbidi="on"><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">This article is originally copied from <a href="http://jangosteve.com/" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-decoration: underline;">Steve Schwartz</a> blog post.</span><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">I have only modified in sense of accessing graphs using nginx as sub directory. </span></div><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Munin is a great tool to monitor resources on your server, showing graphs over time, so that you can analyze resource trends to find what’s killing your server before it causes major problems. It is also very configurable and can be made to profile and graph just about anything via plugins. And with a couple tricks, you can get it to monitor your Phusion Passenger application with ease.<br />
Update: If you have RVM installed on your server and need Munin to work with RVM’s Passenger installation, follow all of the instructions below, and then make the changes described in Monitor Passenger with Munin when using RVM(<a class="external" href="http://tech.tjscreations.com/web/monitor-passenger-with-munin-when-using-rvm/" style="background-image: url(http://projectpath.liviatech.com/images/external.png); background-position: 0% 60%; background-repeat: no-repeat no-repeat; padding-left: 12px; text-decoration: none;">http://tech.tjscreations.com/web/monitor-passenger-with-munin-when-using-rvm/</a>).*<br />
These changes will still use your server’s non-RVM-installed default Ruby to run the Munin plugin, which will in turn use your RVM-installed Ruby to run the passenger-status and passenger-memory-stats commands.<br />
If you already have Munin installed and working, and just want to know how to get the Passenger Plugins working, you can skip directly to Install Munin Passenger Plugins, Configure Munin for Passenger Stats, and be sure to read the Gotcha.<br />
<h2 id="Install-Munin-and-Munin-node" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Install Munin and Munin-node</h2>The first step is to install Munin. If you have your server running Ubuntu, this is pretty easy. One you’ve SSH’d into your server, enter:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo apt-get install munin munin-node -y
</pre>If you’re running another flavor of Linux, see the Munin’s Linux install instructions. For Mac OSX, see Mac install instructions.<br />
<h2 id="Install-Munin-Passenger-Plugins" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Install Munin Passenger Plugins</h2>The next step is to install the Passenger plugins. The first is passenger_status:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">wget http://gist.github.com/20319.txt
</pre>Modify passenger-status path in file 20319.txt, as per your path of passenger-status.<br />
Tip: Use sudo find / -name passenger-status<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo mv 20319.txt /usr/share/munin/plugins/passenger_status
sudo chmod a+x /usr/share/munin/plugins/passenger_status
sudo ln -s /usr/share/munin/plugins/passenger_status /etc/munin/plugins/passenger_status
</pre>The second plugin is passenger_memory_stats:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">wget http://gist.github.com/21391.txt
</pre>Modify passenger_memory_stats path in file 21391.txt, as per your path of passenger_memory_stats.<br />
Tip: Use sudo find / -name passenger_memory_stats<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo mv 21391.txt /usr/share/munin/plugins/passenger_memory_stats
sudo chmod a+x /usr/share/munin/plugins/passenger_memory_stats
sudo ln -s /usr/share/munin/plugins/passenger_memory_stats /etc/munin/plugins/passenger_memory_stats
</pre>No go ahead and restart Munin-node (this is the process that runs Munin at regular intervals):<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo /etc/init.d/munin-node restart
</pre><h2 id="Configure-Munin" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Configure Munin</h2>Now here are where those couple of tricks come in to get Munin playing nicely with your Rails application. First we want to tell Munin where to store the html and graph images that you can access through the browser.<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo nano /etc/munin/munin.conf
</pre>And change the following lines:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">htmldir /path/to/your/rails/public/munin
[yoursite.com]
</pre>Note that the htmldir can really be any directory, but make sure it’s persistent (i.e. if you’re using Capistrano to keep revisions of your app on the server, make sure the munin directory is in the shared directory outside of your rails app root directory).<br />
Also note that the [yoursite.com] part is only a descriptive name, so it really doesn’t matter what you call it. If you have a more complex application that runs from multiple directories or multiple servers, you can group Munin stats, and in this case, you actually have to put some thought into this line. But that’s outside the scope of this article, so you can read up on customizing Munin Master on your own time if you’d like.<br />
Now if you haven’t already, you need to actually create that directory you just told Munin about:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">cd /path/to/your/rails/public
mkdir -p munin
sudo chown munin:munin munin
</pre><h2 id="Configure-Munin-For-Passenger-Stats" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Configure Munin For Passenger Stats</h2>And finally, you need to allow the munin user to run the passenger-status and passenger-memory-stats commands without a password, since they both require sudo powers to run properly.<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo visudo
</pre>And at the bottom of the file add:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">munin ALL=(ALL) NOPASSWD:/usr/bin/passenger-status, /usr/bin/passenger-memory-stats
</pre><h2 id="Gotcha" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Gotcha</h2>At this point, Munin is suppose to start doing it’s stuff and all is happy in the ruby-munin marriage. For me, however, this was not the case. After combing the Munin error logs and digging through the Munin documentation and code more than I care to admit, I realized that Munin-node needs to preface the passenger stat commands with ruby. So, here’s how we fix that:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo nano /etc/munin/plugin-conf.d/munin-node
</pre>And then add this to the bottom of that file:<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">[passenger_*]
user munin
command ruby %c
</pre><h2 id="Final-Munin-Restart" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Final Munin Restart</h2>Now we’ll give Munin-node one more restart and we’re in business.<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo /etc/init.d/munin-node restart
</pre>After waiting a few minutes, you should start to see .html files and graphs and whatnot in the /path/to/your/rails/shared/directory/munin directory. If not, you want to check out the Munin-node error logs to see what’s going on. On Ubuntu, this is found at /var/log/munin/munin-node.log.<br />
<h2 id="Access-Munin" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Access Munin</h2><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">http(s)://your-rails-app/munin/index.html </pre><h2 id="Reference" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;"><span class="Apple-style-span" style="color: #484848; font-weight: normal;"><h2 id="Access-munin-as-a-part-of-rails-aplication-using-nginx" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;"><span class="Apple-style-span" style="color: #484848; font-weight: normal;"><h2 id="Access-munin-as-a-part-of-rails-aplication-using-nginx" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;"><span class="Apple-style-span" style="color: #484848; font-weight: normal;"><span class="Apple-style-span" style="font-size: small;"><h2 id="Access-munin-as-a-part-of-rails-aplication-using-nginx" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Access munin as a part of rails aplication using nginx</h2>You can access munin as part of you rails application using nginx's location directive<br />
Add following lines into your rails application server tag of nginx,<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">location /munin {
root path_to_your_munin_folder;
index index.html index.htm;
}
</pre><h2 id="Reference" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Reference</h2><a class="external" href="http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin#install-munin-passenger-plugins" style="background-image: url(http://projectpath.liviatech.com/images/external.png); background-position: 0% 60%; background-repeat: no-repeat no-repeat; color: #2a5685; padding-left: 12px; text-decoration: none;">http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin#install-munin-passenger-plugins</a></span></span></h2></span></h2></span></h2></span></div></div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-10927810593625505242011-02-13T23:24:00.002+05:302011-10-12T17:05:25.651+05:30REE garbage collector performance tuning<div dir="ltr" style="text-align: left;" trbidi="on"><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"></span><br />
Ruby’s garbage collector tries to adapt memory usage to the amount of memory used by the program by dynamically growing or shrinking the allocated heap as it sees fit. For long running server applications, this approach isn’t always the most efficient one. The performance very much depends on the ratio heap_size / program_size. It behaves somewhat erratic: adding code can actually make your program run faster.<br />
With REE, one can tune the garbage collector’s behavior for better server performance. It is possible to specify the initial heap size to start with. The heap size will never drop below the initial size. By carefully selecting the initial heap size one can decrease startup time and increase throughput of server applications.<br />
Garbage collector behavior is controlled through the following environment variables. These environment variables must be set prior to invoking the Ruby interpreter.<br />
<ul><li>RUBY_HEAP_MIN_SLOTS<div style="margin-top: 0px;">This specifies the initial number of heap slots. The default is 10000.</div></li>
</ul><ul><li>RUBY_HEAP_SLOTS_INCREMENT<div style="margin-top: 0px;">The number of additional heap slots to allocate when Ruby needs to allocate new heap slots for the first time. The default is 10000.<br />
For example, suppose that the default GC settings are in effect, and 10000 Ruby objects exist on the heap (= 10000 used heap slots). When the program creates another object, Ruby will allocate a new heap with 10000 heap slots in it. There are now 20000 heap slots in total, of which 10001 are used and 9999 are unused.</div></li>
</ul><ul><li>RUBY_HEAP_SLOTS_GROWTH_FACTOR<div style="margin-top: 0px;">Multiplicator used for calculating the number of new heaps slots to allocate next time Ruby needs new heap slots. The default is 1.8.<br />
Take the program in the last example. Suppose that the program creates 10000 more objects. Upon creating the 10000th object, Ruby needs to allocate another heap. This heap will have 10000 * 1.8 = 18000 heap slots. There are now 20000 + 18000 = 38000 heap slots in total, of which 20001 are used and 17999 are unused.<br />
The next time Ruby needs to allocate a new heap, that heap will have 18000 * 1.8 = 32400 heap slots.</div></li>
</ul><ul><li>RUBY_GC_MALLOC_LIMIT<div style="margin-top: 0px;">The amount of C data structures which can be allocated without triggering a garbage collection. If this is set too low, then the garbage collector will be started even if there are empty heap slots available. The default value is 8000000.</div></li>
</ul><ul><li>RUBY_HEAP_FREE_MIN<div style="margin-top: 0px;">The number of heap slots that should be available after a garbage collector run. If fewer heap slots are available, then Ruby will allocate a new heap according to the RUBY_HEAP_SLOTS_INCREMENT and RUBY_HEAP_SLOTS_GROWTH_FACTOR parameters. The default value is 4096.</div></li>
</ul><h2 id="GC-configuration-With-respect-to-Livia-portal" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; font-family: 'Trebuchet MS', Verdana, sans-serif; font-size: 16px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">GC configuration With respect to my portal</h2>As mentioned into coffeepowdered.net(reference link), we have used scrap plugin.<br />
It's given following statistic<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">Number of objects : 2181349 (1735589 AST nodes, 79.56%)
Heap slot size : 40
GC cycles so far : 415
Number of heaps : 9
Total size of objects: 85208.95 KB
Total size of heaps : 119579.90 KB (34370.95 KB = 28.74% unused)
Leading free slots : 389261 (15205.51 KB = 12.72%)
Trailing free slots : 2 (0.08 KB = 0.00%)
Number of contiguous groups of 16 slots: 38143 (19.94%)
Number of terminal objects: 6617 (0.22%)
</pre>As, you see in the statistic, we required 9 heaps slot to feet 2181349 objects. To reduce this to feet into single heap we have added following configuration.<br />
1. Created a file with any name. e.g<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo vi /opt/ruby-enterprise-1.8.7-2010.02/bin/ruby_with_env
</pre>2. Added following line in it<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">#!/bin/bash
export RUBY_HEAP_MIN_SLOTS=2500000
export RUBY_HEAP_SLOTS_INCREMENT=200000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=40000000
export RUBY_HEAP_FREE_MIN=25000
exec "/opt/ruby-enterprise-1.8.7-2010.02/bin/ruby" "$@"
</pre>3. Given execute permission to it<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo chmod +x /opt/ruby-enterprise-1.8.7-2010.02/bin/ruby_with_env
</pre>4. As we using passenger, so we have modified nginx.conf to use above configuration,<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">passenger_ruby /opt/ruby-enterprise-1.8.7-2010.02/bin/ruby;
</pre>with<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">passenger_ruby /opt/ruby-enterprise-1.8.7-2010.02/bin/ruby_with_env;
</pre>After doing this configuration, we got following statistic,<br />
<pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">Number of objects : 2093655 (1698545 AST nodes, 81.13%)
Heap slot size : 40
GC cycles so far : 14
Number of heaps : 1
Total size of objects: 81783.40 KB
Total size of heaps : 97656.29 KB (15872.89 KB = 16.25% unused)
Leading free slots : 406346 (15872.89 KB = 16.25%)
Trailing free slots : 0 (0.00 KB = 0.00%)
Number of contiguous groups of 16 slots: 25396 (16.25%)
Number of terminal objects: 6993 (0.28%)
</pre>As you can see two important variables are come down drastically.<br />
<strong>GC cycles so far : 14</strong><br />
<strong>Number of heaps : 1</strong><br />
<strong><br />
</strong><br />
<strong><span class="Apple-style-span" style="font-weight: normal;"></span></strong><br />
<h2 id="Reference" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; font-family: 'Trebuchet MS', Verdana, sans-serif; font-size: 16px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;"><strong>Reference</strong></h2><strong><a class="external" href="http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector" style="background-image: url(http://projectpath.liviatech.com/images/external.png); background-position: 0% 60%; background-repeat: no-repeat no-repeat; color: #2a5685; padding-left: 12px; text-decoration: none;">http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector</a><br />
<a class="external" href="http://www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/" style="background-image: url(http://projectpath.liviatech.com/images/external.png); background-position: 0% 60%; background-repeat: no-repeat no-repeat; color: #2a5685; padding-left: 12px; text-decoration: none;">http://www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/</a></strong><br />
<br />
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0tag:blogger.com,1999:blog-5615275573872642580.post-7364570827864786312011-02-13T18:47:00.000+05:302011-02-13T18:47:07.900+05:30Monitor rails instances of passenger in Nginx<div dir="ltr" style="text-align: left;" trbidi="on"><br />
A month back, we have faced an issue of memory out of space which leads the server crash. We have solved this issue with help of following script. This script is sending an kill signal rails instance which is taking a more memory. Due to this crash will be get notified at client side.<br />
<br />
This script is use full for monitoring rails instance of passenger. As other available tools are not able to monitor rails instance which is maintained by passenger.<br />
<br />
It will monitor rails instance such that, it will kill rails instance which is taking more than 500MB and if rails instance has processed 200 requests.<br />
<br />
After killing rails instance, passenger will automatically fork another rails instance if required.<br />
<br />
The reason of restarting instance after certain requests, to keep memory available for other rails instances. Since I have found an articles which are saying "Rails expands the Ruby process so much that additional memory allocation grows much larger than we actually need, due to the exponential growth factor. And since MRI never gives back unused memory"<br />
<br />
I have saw passenger has PassengerMaxRequests and PassengerMaxMemory (Not sure) for Apache server but not available for nginx.<br />
<br />
My script will do the same thing for nginx :).<br />
<br />
<br />
<div style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;">Open any file,<br />
e.g</div><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">vi monitor_rails_instance
</pre></span><div style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;">and paste following code in it.</div><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;"><code class="sh syntaxhl"><span class="CodeRay"><span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 1</span> #!/bin/sh
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 2</span>
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 3</span> while true; do
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 4</span>
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 5</span> passenger-memory-stats | grep Rails:\ /home | awk ' { if($2 > 500) print "kill -9 " $1}' | bash
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 6</span> # above line will kill all the rails instances which are using memory more than 500MB
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 7</span>
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 8</span> passenger-status | grep Processed: | awk ' { if($7 > 200) print "kill -6 " $3}' | bash
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"> 9</span> # above line will abort all rails instance who have processed 200 request.
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;"><strong>10</strong></span>
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;">11</span> sleep 2
<span class="no" style="background-color: #eeeeee; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; padding-top: 2px;">12</span> done
</span></code></pre></span><div style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;">Then give execute permission to the file</div><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo chmod +x monitor_rails_instance
</pre></span><div style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;">And then run this script as super user</div><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo ./monitor_rails_instance
</pre></span><h2 id="Note" style="border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; color: #444444; font-family: 'Trebuchet MS', Verdana, sans-serif; font-size: 16px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 0px; padding-right: 10px; padding-top: 2px;">Note:</h2><div style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;">If you want to run this script as background process on server</div><span class="Apple-style-span" style="color: #484848; font-family: Verdana, sans-serif; font-size: 12px;"><pre style="background-color: #fafafa; border-bottom-color: rgb(218, 218, 218); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(218, 218, 218); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(218, 218, 218); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(218, 218, 218); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1.6em; margin-right: 1em; margin-top: 1em; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; padding-left: 0px; padding-right: 2px; padding-top: 2px; width: auto;">sudo nohup ./monitor_rails_instance</pre></span><br />
</div>Rahul Chaudharihttp://www.blogger.com/profile/03485442954720708842noreply@blogger.com0