Photo-1 Photo-2 Photo-3 Photo-4 Photo-5 Photo-6

@brentmc79

@brentmc79

Full-time web developer. Part-time smart ass.

I'm Brent Collier.

After a year and a half as an engineer on Twitter's Trust & Safety team, I'm looking for my next gig. Contact me if you know of something interesting.

#

backgroundrb troubles

Posted on 09/16/2008

So I recently spent several days upgrading an outdated backgroundrb install to the latest version.  The Backgroundrb documentation is a bit sparse, so needless to say, I quickly became an active member of the mailing list.

Actually, to be honest, I didn't end up joining the mailing list until after I spent nearly an entire day pulling my hair out over a very strange bug.

Basically, I would create a new worker, send it some work to do, and then nothing would happen.  The code looked something like this:

key = MiddleMan.new_worker(:worker => :prince_xml_worker, :worker_key => worker_key)
    worker = MiddleMan.worker(:prince_xml_worker, key)
    worker.async_build_pdf(:arg => html_string) 
    

(I was working on pdf generation in case you couldn't tell)

A little tailing of the background_debug log told me that I was requesting work on an invalid worker.  An invalid worker?  How could it not be valid?  I just created the freakin thing.  I thought maybe the key was wrong or something, so I added a debugger after the 'new_worker' line and tested it out.  To my frustration, the generated key was perfectly valid, as was the worker retrieved from the middleman.

WTF?

I even managed to call the async worker method from the console and it worked perfectly.  But anytime that I would remove the debugger and let it run its course, nothing would happen.  It seemed ridiculous at first, but I thought maybe it just needs a second before its ready.  Nah...  That couldn't be it.  Just for kicks I put in a half-second sleep call where the debugger was previously, like so:

key = MiddleMan.new_worker(:worker => :prince_xml_worker, :worker_key => worker_key)
    worker = MiddleMan.worker(:prince_xml_worker, key)
    sleep(0.5)
    worker.async_build_pdf(:arg => html_string) 
    

...and it worker perfectly.  

This just seemed crazy, so I got on the mailing list, described my problem and had a response within the hour.  I couldn't believe it, but i was right.  It said that if you're developing on OSX that backgroundrb basically needs a split second to start up the worker, before it can be used.  Since only our development environments were OSX, I conditionally enabled the sleep command based on the RAILS_ENV.  Unfortunately, our staging server, which is a Gentoo machine had the same problem, so I had to update the code accordinly.

ALSO...

Whatever you do, don't put 'puts' statements in your workers.  I ran into the situation where my debugging of code was actually causing it to break, which wasted more time than I'd care to admit.

#

Keeping the pace

Posted on 08/12/2008

I'm currently working on a fairly large rails app that's been in development for the past couple of years. In fact, when it first began I think Rails was only at version 1.1 or 1.2.

A lot's changed since then, both in Rails and the app. I've been doing Rails development for over a year now, but I'm still far from an expert. I often find myself looking at a bit of code and wondering if it's some part of Rails (or ruby) that I'm not familiar with, or if it's something specific to our app. We have a lot of custom framework code, and given the size and age of our app, it's not unlikely.

Well, I found a case today in which it was both. I was in the middle of replacing a bit of classic_pagination with will_paginate and I noticed that it kept choking on hash.except(keys). I thought this was a little odd since it was plugin code, which I was pretty sure we hadn't modified. After a little poking around, I found that the except method was defined in a Hash extension in the lib/ directory. There was no way that will_paginate was referring to a bit of our code!  A quick Google search later, I found that ActiveSupport added the except method to Hash. Clearly one of two things had happened. Either we had implemented our own version of hash.except before it made it into Rails, or it had already been added to ActiveSupport, but we were just lagging behind on our Rails version.

When working in a field where the tools change so rapidly, it's very important to keep up with any changes that are made. This is especially important when the development lifetime of an app spans multiple releases of a framework.

#

Having trouble updating rails?

Posted on 06/18/2008

I was setting up the AAB dev environment on my macbook pro when I realized that I was only running Rails 2.0.2 but AAB wanted 2.1.0.  Ehh...  no big deal I thought.  I opened up Terminal and typed...

$ sudo gem update rails

All the usual output scrolled by, indicating that everything went as expected.  Once it was done I tried to check the rails version and that's when I realized that there was a problem

$ rails -v
/Library/Ruby/Site/1.8/rubygems.rb:377:in `report_activate_error':
RubyGem version error: activesupport(2.0.2 not = 2.1.0) (Gem::LoadError)
from /Library/Ruby/Site/1.8/rubygems.rb:309:in `activate'
from /Library/Ruby/Site/1.8/rubygems.rb:335:in `activate'
from /Library/Ruby/Site/1.8/rubygems.rb:334:in `each'
from /Library/Ruby/Site/1.8/rubygems.rb:334:in `activate'
from /Library/Ruby/Site/1.8/rubygems.rb:76:in
`active_gem_with_options'
from /Library/Ruby/Site/1.8/rubygems.rb:50:in `gem'
from /Library/Ruby/bin/rails:15

So then I ran 'gem list' and saw what was up.

...
actionmailer (2.0.2, 1.3.6, 1.3.3, 1.2.5)
actionpack (2.0.2, 1.13.6, 1.13.3)
actionwebservice (1.2.6, 1.2.3, 1.1.6)
activemerchant (1.1.0)
activerecord (2.0.2, 1.15.6, 1.15.3)
activeresource (2.0.2)
activesupport (2.0.2, 1.4.4, 1.4.2)
...

When I did the rails update, none of the rails dependencies were updated.  I tried the update again, thinking that maybe something had just choked in the process, but it was no luck.  A quick Google search yielded the solution of using update with the --source option and http://gems.rubyonrails.org as the URL.

$ sudo gem update --source http://gems.rubyonrails.org
Updating installed gems
Updating metadata for 13 gems from http://gems.rubyonrails.org/
.............
complete
Updating actionmailer
Updating metadata for 13 gems from http://gems.rubyonrails.org/
.............
complete
Successfully installed activesupport-2.1.0
Successfully installed actionpack-2.1.0
Successfully installed actionmailer-2.1.0
Updating activerecord
Successfully installed activesupport-2.1.0
Successfully installed actionpack-2.1.0
Successfully installed actionmailer-2.1.0
Successfully installed activerecord-2.1.0
Updating activeresource
Successfully installed activesupport-2.1.0
Successfully installed actionpack-2.1.0
Successfully installed actionmailer-2.1.0
Successfully installed activerecord-2.1.0
Successfully installed activeresource-2.1.0
Gems updated: activesupport, actionpack, actionmailer, activesupport, actionpack, actionmailer, activerecord, activesupport, actionpack, actionmailer, activerecord, activeresource

That did it! Now rails and all its dependencies are at 2.1.0.

#

my first hiccup

Posted on 06/04/2008

So I mentioned earlier that I was using Capistrano 2.0.  Well, in actuality, I was using version 2.3.0.  Why's this important?  Well, I'll tell ya....

On my initial deploy:

cap deploy:cold

...everything went fine.  Capistrano did a clone of my Github repo, ran all of my migrations, and started up the mongrels without a hitch.  It was on my subsequent deploy that I had a problem.

macbook:blog brent$ cap deploy
  * executing `deploy'
  * executing `deploy:update'
 ** transaction: start
  * executing `deploy:update_code'
    updating the cached checkout on all servers
ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly
*** [deploy:update_code] rolling back
  * executing "rm -rf /home/brent/public_html/acts-as-blogr.com/releases/20080604051355; true"
    servers: ["acts-as-blogr.com"]
    [acts-as-blogr.com] executing command
    command finished
/Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy/scm/git.rb:217:in `query_revision': Unable to resolve revision for master (RuntimeError)
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `send'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `method_missing'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy/scm/base.rb:63:in `local'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `method_missing'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/recipes/deploy.rb:37:in `load'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/configuration/variables.rb:87:in `call'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/configuration/variables.rb:87:in `fetch'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/configuration/variables.rb:110:in `protect'
     ... 35 levels...
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/lib/capistrano/cli/execute.rb:14:in `execute'
    from /Library/Ruby/Gems/1.8/gems/capistrano-2.3.0/bin/cap:4
    from /usr/bin/cap:19:in `load'
    from /usr/bin/cap:19

I tried again and got the same results.  After a quick google or two, I found this Lighthouse ticket for Capistrano. Evidently there's an issue with cap version 2.3.0 in which it calls 'fetch --tags' to update your code, which returns only tag commits instead of all commits.  This is a problem.

Fortunately, the solution is a simple as either downgrading to version 2.2.0, or upgrading to the latest build.  I opted for the safe route and installed 2.2.0.  Now everything is right as rain.