Is this your first visit? You may want to subscribe to the feed.

Articles tagged with gem

delayed_job 2.0

I’ve pushed out the delayed_job 2.0 gem from the Collective Idea fork on GitHub. See the changelog for a summary of changes, or see the full list changes.

Multiple Backends

One of the most significant changes was adding support for multiple backends. You can now use Active Record, MongoMapper, or DataMapper as backends for your job queue. See the README for more info.

Benchmarks

The Active Record backend in delayed_job 2.0 is much faster (6x in the benchmarks I ran), primarily due to reversing the priority column and adding an index. Here are benchmarks for running 10,000 simple jobs on my laptop:

                      user     system      total        real
delayed_job 1.8.5 195.670000  14.020000  209.690000 (230.887172)
delayed_job 2.0    36.200000   0.940000  37.140000  ( 39.959233)

While we’re looking at benchmarks, here is how the current backends compare:

                     user     system      total        real
active_record      36.200000   0.940000  37.140000 ( 39.959233)
mongo_mapper       69.270000   3.220000  72.490000 ( 90.783220)
data_mapper       255.620000   2.880000 258.500000 (275.550383)

I have not done anything to optimize the mongo_mapper or data_mapper backend, so performance patches would be appreciated.

Upgrading

To take full advantage of the Active Record performance improvements, you’ll want to add an index:

add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'

The only other issue that most people will run into is that all of the configuration options have been moved to Delayed::Worker. Here’s how to change the options now:

Delayed::Worker.destroy_failed_jobs = false   # Delayed::Job.destroy_failed_jobs = false
Delayed::Worker.max_attempts = 3              # Delayed::Job.const_set("MAX_ATTEMPTS", 3)
Delayed::Worker.max_run_time = 5.minutes      # Delayed::Job.const_set("MAX_RUN_TIME", 5.minutes)
Delayed::Worker.sleep_delay = 60              # Delayed::Worker.const_set("SLEEP", 60)

Feel free to post any comments or questions on the mailing list.

Code: gem Apr 03, 2010 ● updated Apr 03, 2010 3 comments

Graticule and MapQuest?

MapQuest has sent out several emails about their current geocoding API being discontinued. Here is the latest:

Dear MapQuest Platform Customer,

At the start of the New Year, MapQuest will be retiring the MapQuest OpenAPI product, having launched the more feature rich MapQuest Platform: Free Edition product. Since the MapQuest OpenAPI does not use the same backend as our newer APIs, nor does it provide the breadth in functionality, we want to provide you with a better free experience. Don’t wait – make the switch today!

If your application is currently being powered by the MapQuest OpenAPI product, you will need to migrate to one of 6 APIs available in the MapQuest Platform: Free Edition product prior to January 31, 2009.

Our MapQuest Platform: Free Edition product offers more flexibility and ease of development along with providing developer choice with six APIs:

SERVER SIDE APIs Java C++ .NET

CLIENT SIDE APIs JavaScript AS3 (ActionScript 3: Flash, Flex, AIR) FUJAX (Write JavaScript, output Flash)

Our MapQuest Platform: Free Edition product includes many additional features including:
  • COLLECTIONS: Support for multiple and remote collections (KML and GeoRSS); allowing easier handling of shape collections.
  • ADVANCED SHAPE OVERLAYS: Build applications that allow users to create and interact with a variety of overlays on maps, including custom lines, polygons, rectangles, and ellipses.
  • CUSTOM TILE LAYER SUPPORT.
  • Add REAL-TIME TRAFFIC to your map.
  • GLOBE VIEW: http://globe.mapquest.com.
  • AERIAL IMAGERY and HYBRID VIEWS.
  • SMART ROLLOVERS: Rollover windows that adapt their size and positioning based on the content placed in the window.
  • ADVANCED MAP MARKERS: With the MapQuest “declutter mode,” automatically move collided markers to positions on the map with a leader link pointing to their original location.

The MapQuest OpenAPI product servers will go offline on Saturday, January 31st, 2009. Please plan on migrating your application before this date or applications based on the MapQuest OpenAPI product will stop working.

You can find documentation and downloads for the MapQuest Platform: Free Edition product on our Developer Network: http://developer.mapquest.com.

Additional information can be found on: http://platform.mapquest.com & http://devblog.mapquest.com.

Thank you,

MapQuest, Inc.

Graticule, a ruby wrapper around many popular geocoding APIs, uses the old MapQuest API. I don’t use it, and I don’t know if anyone else does, so I’m leaving it to you, lazyweb: If you use the MapQuest API, or want to in the future, fork graticule on GitHub and update the MapQuest wrapper.

Code: gem Dec 13, 2008 ● updated Dec 13, 2008 0 comments

Money with precision

I’ve been working on a project that needs to store mileage reimbursement rates to the nearest tenth of a cent. We were using the money gem, which stores money amounts in cents, so it looked like it was going to be a pain.

But without too much suffering, I modified the money gem to take a precision (in powers of 10), which defaults to 2. It can now store amounts in any precision.

>> amount = 20.to_money + 0.505.to_money
=> #<Money @precision=3, @currency="USD", @cents=20505>
>> amount.to_s
=> "20.505"
>> amount.format
=> "$20.51"

You can also store amounts in negative precisions, like millions:

>> amount = Money.new(50, 'USD', -6)
>> amount.to_s
=> "50"
>> amount.format
=> "$50000000.00"

Check out our fork of the money gem on github. There are lots of other goodies in there.

Code: gem Oct 18, 2008 ● updated Oct 18, 2008 2 comments

Autotest mapping for Rails test conventions

A while ago I posted a configuration for getting autotest to work with Test::Unit outside of Rails. Ryan Davis, author of autotest, commented on that post saying that it should “Just Work™” without any custom configuration. I was perplexed because I’ve never been able to get it to work on my gems and Rails plugins.

I finally took time to look into the issue, and realized it’s because I always use the Rails naming conventions for my test files. I name them foo_test.rb, instead of test_foo.rb, which is what Autotest looks for.

That’s easily solvable. Here’s an Autotest configuration, tested with ZenTest 3.10.0, that should make it work for either naming convention. You can throw this in your ~/.autotest file, or in a .autotest file inside your project.

Autotest.add_hook :initialize do |at|
  at.clear_mappings

  at.add_mapping %r%/^lib/(.*)\.rb$% do |_, m|
    possible = File.basename(m[1])
    files_matching %r%^test/.*(#{possible}_test|test_#{possible})\.rb$%
  end

  at.add_mapping(%r%^test/.*\.rb$%) {|filename, _| filename }
end

Happy autotesting.

Code: gem Aug 22, 2008 ● updated Oct 14, 2008 1 comment

Tinder fixed after Campfire update

A week or so ago, 37 Signals released an update to Campfire that broke the ability to listen in a room with Tinder. Version 0.1.5 of Tinder has been released, which fixes the Room#listen method.

Code: gem Jan 25, 2008 ● updated Oct 14, 2008 1 comment

Autotest without Rails

Autotest is a gem (well, technically ZenTest is a gem that includes autotest). But seriously, autotest is a gem! I can’t write code without it anymore. It has become my coding security blanket.

I started going through withdrawal last night while I was working on a Ruby library because autotest doesn’t work out of the box with plain ol’ Ruby projects. It assumes you’re using one of the Ruby web frameworks.

Here’s how to remedy that.

Aizatto shows us how to use autotest with your Rails plugins and RSpec. That’s a great start, but unfortunately, not all of my projects use RSpec (yet), and not all of them are Rails plugins.

To make autotest work with Test::Unit, we need to tell it how to map files to their tests. Here is a simple mapping that maps each ruby file in lib/ to the a corresponding test test/*_test.rb. For example, lib/foo/bar.rb would map to to a test in test/foo/bar_test.rb.

# autotest/testunit.rb
require 'autotest'

class Autotest::Testunit < Autotest
  def initialize # :nodoc:
    super
    @exceptions = /^\.\/(?:config|doc|log|tmp|website)/

    @test_mappings = {
      %r%^test/.*\.rb$% => proc { |filename, _|
        filename
      },
      %r%^lib/(.*)\.rb$% => proc { |_, m|
        ["test/#{m[1]}_test.rb"]
      },
      %r%^test/test_helper.rb$% => proc {
        files_matching %r%^test/.*_test\.rb$%
      },
    }
  end

  # Given the string filename as the path, determine
  # the corresponding tests for it, in an array.
  def tests_for_file(filename)
    super.select { |f| @files.has_key? f }
  end
end

We have the mapping, now all we need to do is tell autotest about it.

# autotest/discover.rb
require File.dirname(__FILE__) + '/testunit'

Autotest.add_discovery { "testunit" }

Throw both of those files into a autotest/ directory in your plain ol’ Ruby project and autotest should just work for you.

Extra credit: Make it work with RSpec on plain ol’ Ruby projects.

Code: gem Dec 06, 2007 ● updated Dec 06, 2007 6 comments

Tinder: Listening is just as important as speaking

I just released an update to Tinder, the really unofficial Campfire API, that allows listening in on a room:

campfire = Tinder::Campfire.new 'mysubdomain'
campfire.login 'myemail@example.com', 'mypassword'

room = campfire.find_room_by_name 'Room 1'

messages = room.listen
#=> [{:person=>"Brandon", :message=>"I'm getting very sleepy", :user_id=>"148583", :id=>"16434003"}]
#listen takes an option block, which causes it to poll for new messages every 5 seconds and call the block for each message. It works great for heckling (ok, maybe that’s not the intent):
room.listen do |m|
  room.speak "You're dumb!" if m[:person] == 'Brandon'
end

Check out my original post for more information about Tinder. Feedback and patches are welcome!

Thanks to Jesse Newland for the listening code.

Code: gem Jan 27, 2007 ● updated Jan 27, 2007 14 comments

Subscribe

Browse by Tag