Category Archives: ruby

BackgrounDRb best practises

  • Best place for BackgrounDRb documentation is the README file that comes with the plugin. Read it thoroughly before going anywhere else for documentation.
  • When passing arguments from Rails to BackgrounDRb workers, don’t pass huge ActiveRecord objects. Its asking for trouble. You can easily circumvent the situation by passing id of AR objects.
  • Its always a good idea to run trunk version rather than older tag releases.
  • To debug backgroundrb problems. Its always a good idea to start bdrb in foreground mode by skipping ‘start’ argument while starting the bdrb server. After that, you should fire rails console and try invoking bdrb tasks from rails console and find out whats happening. John Yerhot has posted an excellent write up about this, here
  • Whenever you update the plugin code from svn, don’t forget to remove old backgroundrb script and run :
     rake backgroundrb:setup
  • When deploying the plugin in production, please change backgroundrb.yml, so as production environment is loaded in backgroundrb server. You should avoid keeping backgroundrb.yml file in svn. Rather, you should have a cap task that generates backgroundrb.yml on production servers.
  • When you are processing too many tasks from rails, you should use inbuilt thread pool, rather than firing new workers
  • BackgrounDRb needs Ruby >= 1.8.5
  • When you are starting a worker using
     MiddleMan.new_worker() 

    from rails and using a job_key to start the worker ( You must use unique job keys anyways, if you want more than one instance of same worker running at the same time ), you must always access that instance of worker with same job key. Thats all MiddleMan methods that will invoke a method on that instance of worker must carry job_key as a parameter. For example:

    1
    2
    
       session[:job_key] = MiddleMan.new_worker(:worker => :fibonacci_worker, :job_key => 'the_key', :data => params[:input])
       MiddleMan.send_request(:worker => :fibonacci_worker, :worker_method => :do_work, :data => params[:input],:job_key => session[:job_key])

    Omitting the job_key in subsequent calls will be an error, if your worker is started with a job_key.

The Ruby Raven

You might have heard of Raven . Its a rake and Rubygems based tool for building/managing Java projects.

Looks like upgrades to rake and rubygems has broke raven and my search for “Ruby Raven” led me to this:

Quite amusing.

BackgrounDRb 1.0 released

Although its been quite sometime since 1.0 release of BackgrounDRb has been out in the wild, yet a belated post mentioning its features is nonetheless welcome.

Although README document available at, http://backgroundrb.rubyforge.org is quite comprehensive and there is precious little I can add, yet I shall try.

  • BackgrounDRb is a Ruby job server and scheduler. Its main intent is to be
    used with Ruby on Rails applications for offloading long-running tasks. However unlike other libraries BackgrounDRb offers tight integration with Rails and hence you can check status of your workers, pass data to workers and get response back, register status of your workers, dynamically start or stop workers from rails and stuff like that.
  • BackgrounDRb doesn’t have any DRb in its skin now. Its based on networking library packet, (http://packet.googlecode.com)
  • Its stable.
  • It has support for thread_pools, storing of results in MemCache clusters
  • It comes with its own scheduler and hence you don’t need to muck around with crontab anymore

A Quick overview of installation:

  • Get the plugin using:
     piston import http://svn.devjavu.com/backgroundrb/trunk/ backgroundrb
  • Remove or backup older backgroundrb scripts/config files in your rails root directory
  • Run following command from root directory of your rails app:
     rake backgroundrb:setup
  • Have a look at generated config file, RAILS_ROOT/config/backgroundrb.yml and see if there is anything you would like to change.
  • Generate a new worker using :
     ./script/generate worker foo
  • Read the detail documentation about writing workers and stuff on http://backgroundrb.rubyforge.org
  • Start your BackgrounDRb server with:
    ./script/backgroundrb start
  • Stop your BackgrounDRb server with:
    ./script/backgroundrb stop

Special Weapons And Tactics ( SWAT ) app

Updates
Getting gtk-ruby installed is a bit tricky, look into the comments for getting it installed. Also, you don’t necessarily need Emacs to use this application.

Another important thing is, it stores your todos and metadata files in a directory called, ~/snippets, so make sure you have that directory. Although newer version of app, automatically checks for the directory. I put up lots of bug fixes, and a tab for viewing completed tasks too, So make sure you are using latest version. Thanks.

Version 1.0.2 of Swat App

Install it with:

sudo gem install swat-1.0.2.gem

Hey there,

Curse me for making this app if you will. But the truth is all the todo applications in GNU/Linux suck, then I thought ok, may be they do not suck enough. So, with some ruby skills at my disposal, I wrote a todo application in Gtk Ruby.

swat App Small

So whats swat?

Swat is a todo list manager for Gnome & Emacs.

Heck : Emacs?

Features:

  • Manage your todos, add them according to priority and category.
  • Move your todos to wish list, when not feeling like working on them.
  • libtomboy bindings for global shortcut(Alt-F11).
  • Nice stats for number of tasks finished and added.
  • All your todos are in a .org file and hence can be managed from Emacs as well.
  • System tray integration.

KeyBindings:

  • Alt-F11 : from anywhere, brings the todo window to front.
  • Esc : to dismiss todo window.
  • Control-N : to add a todo.

Installation :

  • sudo gem install swat

Code:

  • http://packet.googlecode.com/svn/branches/swat/

New release of BackgrounDRb available now

Assuming nobody is reading this, I would quietly mention that, I released new version of BackgrounDRb plugin today.
Checkout full announcement here:

http://rubyforge.org/pipermail/backgroundrb-devel/2007-November/001043.html

Here is a sample worker:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class FooWorker < BackgrounDRb::MetaWorker
  set_worker_name :foo_worker
  attr_accessor :count
 
  def create
    puts "Starting Foo Worker"
    @count = 0
    add_periodic_timer(4) { increment_status}
  end
 
  def process_request p_data
    user_input = p_data[:data]
    result = self.send(user_input[:method],user_input[:data])
    send_response(p_data,result)
  end
 
  def increment_status
    puts "Registering status"
    register_status("stuff #{rand(10)}")
  end
 
  def foobar
    puts "Invoking foobar at #{Time.now}"
  end
 
  def add_values user_input
    p user_input
    return eval(user_input)
  end
end
 
=begin
  problems, with existing things.
=end

#ruby-talk gems of the week

If you have any hopes of becoming a Ruby guru, then regular dose of ruby-talk is a must. In this post, I would try to summarize some of the cool stuffs being discussed on ruby-talk.

  • In Ruby, having method names that contain “-” can be PITA. So David Black and others were quick to point following approach of doing so:

    1
    2
    3
    4
    5
    
    irb(main):002:0> class C
    irb(main):003:1>   define_method("x-y") { puts "Weird method" }
    irb(main):004:1> end
    # At which point, the only way to call it is:
    irb(main):005:0> C.new.send("x-y")   # Weird method

    In other words, it’s not worth the trouble and you should find some
    other solution.

  • Trans asked on ruby-talk, how can we know, which files are loading or requiring this file. Ara pointed following solution:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    p Kernel.requiree('main')
     
    require 'b'
     
    p Kernel.requiree('main')
     
    BEGIN {
      module Kernel
        h = Hash.new
        define_method(:requiree) do |of|
          h[of]
        end
     
        r = method :require
        define_method(:require) do |*a|
          r.call *a
          h[a.first] = caller
        end
      end
    }

    The interesting bit around, should be noted.

    1
    
      r = method :require

    When you call method and pass method name as a parameter, it returns a closure. Although as pointed by someone it breaks “Rubygems”, and above approach shouldn’t be used. Rather, one should use:

    1
    
      alias_method :old_require, :require

Beware of raising exceptions

I was reading on twitter experience of scaling rails and use of dtrace. Unfortunately for GNU/Linux users “dtrace” is just a unreality. But if you just concentrate on the results, then you will find that, a major source of bottleneck was use of:

  foo = @someobj.amazing rescue "not_amazing"

Above code is in vogue, because it takes care of a lot of things like:

  • if @someobj is nil, then foo defaults to “not_amazing”.
  • if @someobj doesn’t support “amazing” method, foo defaults to “not_amazing”.
  • And of course the obvious case.

But that code succinctness comes at a cost and you may end up with deep stacktraces. This was a major bottleneck for twitter team.
Above snippet can be written as:

foo = @someobject.blank? ? "not_amazing" : (@someobject.respont_do?(:amazing) ? @someobject.amazing : "amazing")

Not so succinct, but does its job.

Read the details http://blogs.sun.com/ahl/entry/dtrace_for_ruby_at_oscon .

Using ‘?’ for wierdness

? is Ruby shorthand for referencing a character.

   irb(main):020:0> ?a => 97 
   irb(main):021:0> ?a == "a"[0] => true
   irb(main):014:0> ?? => 63 
   irb(main):015:0> !?? => false 
   irb(main):016:0> !!?? => true

Since ?? equals 63, it is equivalent to true in a boolean test. That means we can negate it with a bang!