Unique Marketing, Guaranteed Results.

Asynchronous Processing with Workling and Starling

June 18th, 2009 by fugufish

When working with applications whose actions may take some time to complete, it may be better to  handle the request asynchronously. A quick and easy way to do this is using Starling and Workling. Starling is a light weight message queue based on the Memcache protocol, and Workling is a simple, lightweight consumer. Setup is dead simple:

First, install Starling:

 sudo gem install starling 

This will install Starling and it’s dependencies (memcache-client and eventmachine) if you don’t already have them.

Now install Workling. This doesn’t have a gemspec so we will install it as a plugin:

cd ~/path_to_your_project
script/plugin install git://github.com/purzelrakete/workling.git

Finally, tell Workling, which will want to use Spawn by default if it is installed on your machine, to use Starling by placing this in your environment.rb:

Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new

That is it for the installation process! Easy. Now for actually handling requests. Believe it or not, it is just as simple as the installation. Say you have a controller that has to do several long running tasks:

class SkinnyController 

Now typically, you should avoid doing things that take longer than a few seconds to complete. And this is okay for most application requirements, however in some cases, it is inevitable that a few tasks will take much longer, such as above. That is where Workling comes in. Simply refactor the code into a worker (conveniently located in app/workers):

# app/workers/fat_worker.rb
class FatWorker 

Now, in your controller, call the worker:

class SkinnyController 

Just start up starling and workling (starling start, and script/workling_client start respectively) And that is all. You can now handle large tasks asynchronously, and because the tasks are queued with starling, the action can be called multiple times, and it will queue up the worker and process it as soon as the previous tasks are complete.

Setting PowerDNS To Ignore Records For Downed Web Sites

June 10th, 2009 by Aaron Murphy

If you are using PowerDNS for round robin on multiple websites, you can set it up so that it will return only the records for sites that are up. I set up a Ruby daemon to monitor sites and connect to the PowerDNS MySQL table used by PowerDNS on Rails. You can use any language or system you like. It just needs to be able to access your PowerDNS database. Read the rest of this entry »

Why Test?

June 10th, 2009 by fugufish

I come to PMA from a large corporation over 40,000 employees strong, including an entire army of QA Engineers testing every change and release we made, something we took full advantage of. At first, I was of the opinion (as many BDD converts) that the process of defining the and testing the code before actually writing the code would slow me down. As I moved more and more to BDD however, I found that I was completing tasks faster. The time saved comes from the ability to define how you expect your application to work. By doing this you will find that your actual code requires much less debugging. Things just seem to work. It continuously surprises me using BDD that things just work, so instead of spending hours looking for a mistyped association, I can spend those hours in actually coding.

Even with an army of QA Engineers, some bugs will sneak through. QA time on untested code takes longer, and debugging the code even longer than that. The release process can go from a day to several days, or even weeks.

With BDD, when new features are added to the application, it as easy as running your spec or test suite to ensure that the original functionality is undamaged. It of course seems like a no brainer to me now. It’s like looking back and remembering when you thought the world was flat, and seeing how narrow minded you were. The moral of the story? Test before you code! You fill find yourself with more time, and less headaches.

Smarter Sequencing in Factory Girl

May 29th, 2009 by Brett Rasmussen

Hal Shearer and I monkey-patched Factory Girl’s sequencing capabilities to allow for pre-defined enumerations to loop through, instead of just infinitely incrementing numbers.

So instead of doing this:

  Factory.sequence :email do |n|
    "[email protected]"
  end

you could do something like this:

  Factory.sequence(:email, ['angela', 'brett', 'alec']) do |name|
    "[email protected]"
  end

It will start over at the beginning when it’s gone through all of them:

>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"

You can also hand it a range (the internal implementation on this is none too efficient, so don’t give it billions at a time):

Factory.sequence(:email, 50..60) do |n|
  "[email protected]"
end

>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"

The infinitely incrementing counter is still available if you want it:

Factory.sequence(:email, %w[angela brett alec]) do |name,i|
  "[email protected]"
end

>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"
>> Factory.next :email
=> "[email protected]"

This sort of thing is useful when you want two different factories to use the same sequence and have some overlap between the two groups. For example, we need a bunch of email addresses to test on, many of which share the same domain:

Factory.sequence(:name, %w[angela brett alec hal debbie tracey jared]) do |name,i|
  "#{name}_#{i}"
end

Factory.sequence(:domain, %w[something.com example.com mydomain.com]) do |domain|
  domain
end

Factory.define(:email_address) do |f|
  f.address { "#{Factory.next(:name)}@#{Factory.next(:domain)}" }
end

>> 20.times { ea = Factory.build :email_address; puts ea.address }
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

For our last trick, the reset method returns both the looping index and the infinite counter back to zero:

>> Factory.reset :name
>> Factory.next :name
=> "angela_0"

Here’s the code to make it happen:

class Factory
  def self.sequence(sequence_name, enum = nil, &blk)
    @@sequences ||= {}

    enum = enum.to_a

    @@sequences[sequence_name] = {
      :enum => enum,
      :index => 0,
      :infinite_counter => 0,
      :template  => blk
    }
  end

  def self.next(sequence_name)
    seq = @@sequences[sequence_name]

    retval = case seq[:template].arity
      when 1
        seq[:template].call(seq[:enum][seq[:index]])
      when 2
        seq[:template].call(seq[:enum][seq[:index]], seq[:infinite_counter])
    end

    seq[:index] = (seq[:index]+1 == seq[:enum].size) ? 0 : seq[:index]+1
    seq[:infinite_counter] += 1
    @@sequences[sequence_name] = seq
    retval
  end

  def self.reset(sequence_name)
    @@sequences[sequence_name][:index] = 0
    @@sequences[sequence_name][:infinite_counter] = 0
  end
end

Just put that into some file–perhaps in your rails lib directory–and make sure that file gets required–probably in your rails config/environment.rb. When doing it by hand like this, you’ll want to make sure your library file is loaded after the factory_girl gem is loaded, or you’ll get weirdness like methods you’ve overridden acting in non-overridden ways and the like; config.after_initialize in your environment.rb’s Rails::Initializer block is your friend.

You can also now use the gem BrettRasmussen-factory_girl from gems.github.com. I mean to submit it as a patch back to the original factory_girl, which I’m sure I’ll have time to do Any Day Now.

Ruby on Rails Spotlight Search in Mac OS Leopard

April 15th, 2009 by Chuck Wood

Have you ever wished you could search the Ruby on Rails API with Spotlight? It turns out that you can!

Mac OS X Leopard’s Spotlight search will search through dictionaries you install on your machine and enable. And, it just turns out that such a dictionary exists for Ruby on Rails written by Priit Haamer. Here’s how to set it up:

Read the rest of this entry »

Tutorial: How to install/setup Cucumber

April 9th, 2009 by Alan Carl Mitchell

This tutorial assumes that you have ruby, rails, and mysql installed on your machine, and doesn’t explain too much about Cucumber and will mostly show you a quick way to get it working. A lot of material is borrowed from this tutorial on setting up RSpec and Factory Girl. It may be useful to look over first, but not necessary.

Read the rest of this entry »

Tutorial: How to Set up Ruby on Rails and MySQL on Mac OSX Leopard

April 7th, 2009 by Chuck Wood

Mac OSX has become extremely popular for Ruby on Rails development. Part of this is the inclusion of Ruby as part of the operating system on Mac OSX Leopard. Here is a quick tutorial on how to get Ruby on Rails and MySQL set up on your Mac OSX Leopard machine. In order to complete this tutorial, you need the Xcode tools installed. You can get them off of the applications disk that came with your mac or from http://developer.apple.com/TOOLS/xcode/.

Read the rest of this entry »

Tutorial: How to install/setup RSpec (and Factory Girl) in Rails

April 3rd, 2009 by Alan Carl Mitchell

This tutorial assumes that you have ruby, rails, and mysql installed on your machine. This tutorial also doesn’t explain much about RSpec or Factory Girl and will just show you a quick way to get them working in a RoR environment.

Read the rest of this entry »

You Don’t Need Custom SQL For Simple Aggregation Using ActiveRecord

April 2nd, 2009 by Aaron Murphy

ActiveRecord allows one to execute an SQL statement directly. I prefer to avoid any ActiveRecord code that uses too much SQL syntax. This way I won’t have to rework any code if the underlying database engine was changed. Some of the simple SQL functions that one may want to do with SQL syntax might be SUM, AVG, COUNT, etc. With ActiveRecord::Calculations::ClassMethods, one can avoid specialized syntax.

#returns the total count of all people
Person.count
# returns the total count of all people with an age over 26
Person.count(:conditions => "age > 26")

The following methods are available: average, count, maximum, minimum, sum

Foreign Key Migrations Plugin

April 2nd, 2009 by Chuck Wood

I worked on a plugin yesterday that would include all of our migration helpers. You can find it on github. Currently, it only does foreign keys work, but eventually, I’d like to have it add unique indexes on columns defined with a :unique => true attribute in the ActiveRecord migration. But for right now, here’s how to use it:

Adding a foreign key that references the id column in another table:

# The column 'id' is assumed in the referenced table.
add_foreign_key :table1, :table2_ref, :table2

Read the rest of this entry »

Copyright © 2005-2016 PMA Media Group. All Rights Reserved &nbsp