New Ruby Gem – Amaze SNS version 1.0.1

Amaze SNS gem on rubygems.org

Amaze SNS rubygem

One of the things which I have always wanted to do is to contribute back to the open source community at large. For years I have been using and adopting other people’s work so its only fair to keep the cycle moving. Since it is my first attempt at creating a ruby gem, I decided to pick an area of usage which is relatively new as well as straight forward to maintain and develop.

This started back in May and Amazon AWS just launched their Simple Notification Service(SNS) for short. After reading through their API and from my earlier brushing with the S3 request protocol for the S3 IPhone App, I had gain more familiarity with how the AWS API calls work and so I made a gem called ‘amaze_sns’ which interfaces with the SNS service.

The Amaze SNS gem is in its stable release and its version is at 1.0.1. Please note – this is different from the amaze-sns gem which has since been yanked from rubygems as it is buggy and not advisable to be used.

To install the latest version, just do

sudo gem install amaze_sns

The source code can be found at http://github.com/cheeyeo/Amazon-SNS-Rubyand the actual rubygems page on http://rubygems.org/gems/amaze_sns

So far, it has received over 400+ downloads since May but that was mainly for the older version – amaze-sns – which due to a fatal flaw I realised did not work. Apologies for those of you who downloaded that earlier version – I’m still learning what else can I say.

Version 1.0.1 is confirmed to work and supports quite a few new nifty features if I may say so

  • You can now set attributes for each topic and the Policy attribute of a topic is JSON parsed so you can access it like a hash
  • EventMachine support is rolled back to the earlier stable version and you can still use your own code blocks to parse the response.
  • Sample code has been provided in the ‘examples’ folder.
  • Fixed some weird bug whereby the Topic actions does not return the response of an action due to the way the EventMachine reactor loop exits on dual core machines running ruby 1.8.7 ??

No doubt this will be an ongoing project as the API is still in a state of flux and so expect further updates as and when they arrive.

Further plans to develop an actual Rails app to showcase it in use in production is in the pipeline.

The eventual goal is to be able to wrap up the requests call within a Rack middleware so it can parse the requests and responses away from the core app.

I have added Pledgie support on the github page – I know it is only a small thing on the whole scale of things but any contribution you make will go towards allowing me to develop this gem further.

Please feel free to forward any links of projects you have used it in and I will showcase it on a dedicated page for it.

Enjoy!

RVM Rocks

I’ve learnt about RVM (Ruby Version Manager) through a contact of mine and decided to try it out for myself as to how easy it is to manage multiple versions of Ruby on one dev machine. And it does exactly what it says on the tin – it just works out of the box!

I already have Ruby 1.9 installed locally with the alias of ‘ruby19′ through a manual install but the problem with that approach is that you would have to reference that directly within your own Ruby scripts and to remember to call ‘irb19′ version of that. Add in multiple versions and you would have a management crisis at hand.

With RVM, it manages all these versions for you without any conflicts. All you need to change from one version to another is to type the following in terminal

rvm 1.9.1 # this switches to ruby 1.9.1 assuming you have it installed

Here’s what I did to install RVM on an OS X 10.5.8 :

Firstly, I installed the gem version of rvm:

sudo gem install rvm

You can run the bash script as documented on the RVM documentation site but I had permission issues on mkdir on here. The important thing to note is not to use sudo as that will present problems further down the road. Ideally the command you want to achieve is ‘rvm ‘ without needing to be root.

Once the gem is installed, I run the following command:

rvm-install

This will install rvm on your local machine, creating a binary at ‘/usr/local/bin/rvm’. Run ‘which rvm’ to make sure it is all working.

The fun part is to install a ruby version of your choice. I went for Ruby 1.9 but you can choose whichever version you want. The command is as simple as :

rvm install 1.9.1

This will fetch a copy of the source and compile it so it will take a while.

Once that is complete, open up a new terminal or tab and type the following:

 rvm list

This is my display on my local machine:


  rvm Rubies

ruby-1.9.1-p378 [ i386 ]

System Ruby
system [ ppc i386 ]

To switch back to your default system verison of ruby just type:

rvm system

In order to see the changes , you would need to switch to a new tab after the RVM and Ruby install or else it does not show up.

In addition I have to append the following two lines at the bottom of both my ‘.bashrc’ and ‘.bash_profile’ files:

 
  if [[ -s /Users/cheeyeo/.rvm/scripts/rvm ]] ; then source /Users/cheeyeo/.rvm/scripts/rvm ; fi

This adds the path to your rvm install on your home directory so you can access the rvm and rvm install commands.

Another quick tip: if you want to use a specific version of Ruby on startup, just set its default:


  rvm --default 

More information and examples can be found on the RVM website: http://rvm.beginrescueend.com/

It is really worth trying out and you will be surprised how much time it saves you on managing multiple ruby versions.

Tagged with:
 

acts_as_xapian numeric range searching

I recently implemented Xapian and the acts_as_xapian plugin into my rails project. However, I ran into the ‘Unknown range’ operation error.

By applying the patches listed here and here, that solves the problem for me.

Please note that the changes have to be made to the ‘acts_as_xapian’ lib file within the vendors directory and then rebuild your index and restart your web app before seeing the changes take effect.

Also, if you are performing a numeric range search don’t prefix the values with ‘:’

For example, searching for ‘prices0..100′ is a numeric range search while ‘prices:low’ is a term search for specific attribute of that model.

 

Using cache_fu with will_paginate

Firstly, apologies for not updating regularly enough (last post was in September – yikes!). We have been busy working on two freelance projects since then: firstly with South East Forum for 55 Degrees; and finally with HiredHelp, which is a service provider listing page for Hermes Technologies based in Ireland.

I want to start off the new series of posts with interesting tidits I learnt while developing on these two projects.

On the HiredHelp website, we try to cache as much of the DB calls as possible using memecached with the cache_fu plugin. One of the obstacles we came across was if we had to cache the index action of say a list of babysitters with pagination added in, the subsequent paginated pages do not show. This is due to the fact that the cache is storing the page as ‘babysitters/index’ and not ‘babysitters?page=xxx’.

You will need to provide a ‘cached_path’ to the caches_action in the controller.

For example:

This is the ‘caches_action’ method within the controller:

  
      caches_action :index, :cache_path => :index_cache_path.to_proc
      
def index @babysitters = Babysitter.cached(:list).paginate(:page => params[:page],:per_page => 10) end
private def index_cache_path p = '' p = params[:page] if params[:page] and params[:page] != 1 'babysitters/' + p end

The ‘cached’ method was provided by cache_fu and calls the method ‘list’ within the Babysitter model. The index_cache_path method simply appends the page params from the wii_paginate plugin to the end of the index url. So pages like ‘babysitters?page=2′ will be cached as ‘babysitters/2′ etc.

Now to expire the paginated pages, I wrote a custom method within my sweepers file:

  
  #within BabysitterSweeper
  
def expire_cache total = (Babysitter.list.size.to_i) if total <= 10 expire_fragment("babysitters/index") else pages = (total % 10) + (total /10) -1 1.upto(pages) do |page| expire_fragment("babysitters/#{page}") end expire_fragment("babysitters/index")
end end

The method computes the number of listings allowed per page as stipulated in the wii_paginate call in the index action. In our case it is 10. If the number of entries is less than 10, that means we only expire the index action. If not, we calculate the number of paginated pages there are. If we have say 22 entries that will be split into 3 paginated pages with 2 pages containing 10 entries and a third page with 2 entries. The ‘expire_cache’ method will expire the fragements labelled ‘babysitters/2′ etc from the index call such as ‘babysitters?page=2′.

Tagged with:
 

Control your Nginx processes using signals

This is a follow up on my previous articles on using the NGINX server. On my older wordpress blog, I highlighted the steps involved in installing and getting NGINX running on your development environment. Here, I would like to share how I manage my nginx processes in the same development environment.

If you use Apache through the Passenger gem, you could type something like this to restart the server gracefully:

  
      sudo apachectl graceful
  

and to shutdown:

  
    sudo apachectl shutdown
  

To do the same in nginx, you would need to type the following:

  
     sudo kill -QUIT `cat /usr/local/nginx/logs/nginx.pid`

What the above command does is to do a graceful shutdown of the master process, which would in turn call shutdown on the worker processes. Note the backticks and the cat command. What it does is to run the cat command on the pid file to grab the pid value and pass it to the QUIT signal.

If you need to reload the server after making changes to the configuration file (i.e. nginx.conf), just do:

  
    sudo kill -HUP `cat /usr/local/nginx/logs/nginx.pid`

More command line options can be found on the NGINX wiki, which even details the sequence of events when signals are sent as well as how to upgrade an entire nginx executable on the fly with 0 downtime.

Sweet!