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!

New Ruby gem AmazeSNS

Hi all,

just a short note that I have released a new plugin on my github account:

http://github.com/cheeyeo/Amazon-SNS-Ruby

I’m still in the process of wrapping up into a gem once the spec tests are passed so please bear with me.

The plugin is designed to integrate with the Amazon Simple Notification Service which is similar to the Pusher service as rolled out by the cool guys at New Bamboo. You can design your next generation of Real Time Web apps using SNS.

For the ‘uninitiated’, RTW (Real Time Web) relies on HTML5 websockets which are bi-directional transport streams between the browser and your app, so the moment you make an update to your app, say added in a new blog post,it can notify all the clients who are designed to listen specifically to that particular event and update the blog page in real time.

Similarly, SNS supports push actions through a ‘publish’ action which enables subscribers to a particular ‘topic’ to receive messages via email or JSON through SMTP and http respectively. So far, I have only tried out the SMTP delivery option and sadly it does not support HTML messages at this point.

One cool feature of the plugin is the performance and scalability of it when I started developing it. Originally it only used a single HTTPClient object connection. After having caught the EventMachine bug and async IO operations I was curious about whether a EM version of it would really speed things up.

I added in EM and ran some benchmarks and here are the results below:

100 requests were made to SNS service backend. As you can see, each httpclient request averages 0.75 secs whereas with EM it only takes 0.27 secs! That is less than half and by using EM in conjunction with EventMachine::HttpRequest or the em-http gem, that also supports Deferrable module in EM which means higher concurrency and parallel requests.

This is my first attempt at writing a gem or plugin so your comments and feedback are welcome as it is not perfect by any means.

I also want to thank the following gem authors: Pusher and Happening, from which AmazeSNS borrows some of its ideas from.

Tagged with:
 

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:
 

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: