Cobalt Edge http://cobaltedge.com Most recent posts at Cobalt Edge posterous.com Tue, 04 Jan 2011 10:25:00 -0800 HotelTonight is Hiring Rails and iOS Developers http://cobaltedge.com/hoteltonight-is-hiring-rails-and-ios-develope http://cobaltedge.com/hoteltonight-is-hiring-rails-and-ios-develope

App_icon_114x114
HotelTonight has job openings for great Rails and iOS developers!  I'm quite excited about this, as our company/product is off to an amazing start, and we're continuing to move fast, and expand.  We'll stay a small and nimble team, but do want additional developers to take things up a notch.  For iOS this opportunity will be building an iPhone app essentially from the ground up, and you should be well versed in Objective-C, Cocoa Touch, iOS SDK, etc.  The Rails gig will likely cover a wide range of areas, as it's a lot more than just an API for the mobile app (there's a lot going on behind the scenes).  We're also looking at mobile-specific web apps/features/functionality.

HotelTonight is an awesome place to work.  We have a truly great team and culture.  We're primarily growing our team in San Francisco (we'll open an office there early this year, currently based in San Mateo), but if you're a great developer, get in touch regardless.  We're all passionate about the mobile space, technology, and travel.  
Developers check out the jobs, but please no outsourcers or recruiters.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Tue, 21 Dec 2010 15:04:30 -0800 HotelTonight - our new iPhone app for same-day hotel bookings http://cobaltedge.com/hoteltonight-our-new-iphone-app-for-same-day http://cobaltedge.com/hoteltonight-our-new-iphone-app-for-same-day This blog has been silent, due to working very hard on HotelTonight.  HotelTonight is a new mobile (iPhone to start) app that makes it super easy to book same-day or last minute hotel stays.  If you've headed into the city for a wedding, or a night on the town, for example, and decide you don't want to drive home; or maybe you're working late and just need to crash for the night, HotelTonight gives you a great rate (much better than if you just walked up to the hotel to see if they had a room).  Furthermore, we allow you to book a room until 2am!  Try that with any other service.  We show you the specific hotels we have (and we have awsome ones like the Ace in New York, or the Nikko in San Francisco).  The app has great photos of the hotels, and information that's important for such last minute bookings.  It's a game changer for hotel bookings.

Media_httpwwwhotelton_kcgta

You can install the iPhone app today, or if you're on Android, BlackBerry, or other mobile platforms, follow us on Twitter, or friend us on FaceBook to find out when we're on other platforms.  Also, even if you don't need it today, it's good to install it now, and get in on the $10 we give you towards your first purchase, whenever that may be.  As soon as you sign up, we add the $10 credit, and it doesn't expire.  We're doing a bunch of other awesome promotional things too.  Check out the Facebook page for how to get a free night, or follow us on Twitter to watch for ways you can snag more credits.

As of today, we're in San Francisco, New York, and LA/Hollywood, but we'll be expanding that shortly.  We work directly with the hotels to get great rates, and make the process as easy as can be.  The HotelTonight team has worked really hard on this, and I've personally really enjoyed building this app, and would love to hear your feedback.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 23 Sep 2010 21:23:07 -0700 DealBase is Hiring Developers http://cobaltedge.com/dealbase-is-hiring-developers http://cobaltedge.com/dealbase-is-hiring-developers
Are you the type of person who checks flipboard before you get out of bed? Is a git-based workflow fundamental to your daily coding?  Is writing Ruby like writing English (only a lot more fun)?  Itching to use Rails 3?  How about Coffeescript?  Do you want to build beautiful user interfaces on top of kick-ass web apps/services?  What about mobile apps; are you yearning to build a great one that uses location, has great design and UX, and will disrupt non-mobile online businesses? Are you masterful at leveraging existing tech when possible and creating purpose-built solutions at other times?  Do you communicate well with an entire team and enjoy having the opportunity to give your opinion?

Yes?  Then DealBase wants to talk to you! We're a well funded travel deals site run by a team who have been very successful in online travel. We have a stellar set of investors (Ron Conway, Founder Collective, and several other prominent valley angels).  We are less than 2 years old and already profitable with over 1 million monthly visitors.  We're adding a lot more to the DealBase.com website and expanding our product line into some exciting new areas and need great people to make it happen. 
 
Why join us? We have a results oriented culture, offer competitive compensation and give you unlimited vacation time. We have fun nights out in San Francisco, go to premiers and crazy events in Vegas and some of us are even doing the NorCal ToughMuddr. We're runners, skiers, foodies, espresso fiends, travelers and passionate about what we do.

Requirements:
  • Demonstrated work experience with Ruby, Rails, JavaScript, HTML, CSS, git, databases, Linux, Mac, and testing (TDD/BDD).
  • Four year college degree
  • Located near one of our offices - San Mateo, CA or Portland, OR
Things we are not interested in:
  • No contractors, outsourcers, development firms, etc. This is a full-time position, where you will be an integral part of the team.
  • No recruiters please
If you're interested, send resume/work experience, cover letter, and information to devjobs@dealbase.com

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Fri, 16 Apr 2010 09:25:46 -0700 Cybercrime Adventures at the Eugene Modern Web Developers Meetup http://cobaltedge.com/cybercrime-adventures-at-the-eugene-modern-we http://cobaltedge.com/cybercrime-adventures-at-the-eugene-modern-we
Last night's Eugene Modern Web Developer's meetup was a lot of fun.  Nick told the story of his real life adventures tracking down a very serious cyber-criminal.  This included reverse engineering rootkits, walls of assembly code printouts with pins and strings to help explain the code (just like you'd see in the movies (well, the pins and string thing, they aren't usually stuck to code)), and building small programs to help investigate (and lead to the apprehension of the primary evil-doer).  He told the story very well, and it was a great time.

This morning I sent the group a bunch of links to things that came up during the talk, or, in the 3 hours after the talk that Rob (@robhudson), Nick, and I hung out and continued to talk.  A bunch of books were mentioned throughout the night, and I think I've covered all of them below, as well as Nick talked a bit about PLT Scheme, and so on.  Here are the links I'd sent out to the group:

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Mon, 12 Apr 2010 23:45:00 -0700 Tricky Rails Callbacks and Deleting Associated Records http://cobaltedge.com/tricky-rails-callbacks-and-deleting-associate http://cobaltedge.com/tricky-rails-callbacks-and-deleting-associate

UPDATE: As it turns out, the below solution was totally rookie!  The whole issue is still there, but the need to solve it with the use of update_all (which is a bit brute force and generally something to avoid for just updating a couple attributes on a single record, it avoids validations, etc, etc.), was not necessary.  As it turns out, there are association callbacks. I'm kind of surprised I hadn't seen this or thought of it.  But, there are callbacks to be notified when associated records are added, or removed (and both the before and after variations). So, instead, instead of setting the update_lowest_and_highest_rates as an after_update, specify an after_remove callback on the association:

  has_many :fares, :after_remove => :update_lowest_and_highest_rates

Then implement the update method like:

  def update_lowest_and_highest_rates

    fares.reload

    set_lowest_and_highest_rates

    save

  end

And note, set_lowest_and_highest_rates, is the same method as the create_lowest_and_highest_rates, just renamed.  It's renamed because now you'd use before_validation or before_save or whatever is needed in your case, instead of the _on_create variant of that.  The rest of the problems are still there (needing to refresh the fares association, and the general aspect of all this, etc.), but this is a much nicer solution I think.

I recently ran into some tricky issues related to deleting records on an association combined with ActiveRecord callbacks.  The issue may seem like an edge case, but from googling for solutions, clearly it's not an uncommon need.  An example will illustrate the problem...

 
I'll use a sort of pseudo-example from DealBase.  Let's take a flight "Deal" model.  It has_many "Fares", which are just prices for the deal from one airport to another.  A Deal accepts_nested_attributes_for Fares.  This lets us edit a deal and all its fares in one form, etc.  As part of this, you can select to delete a fare.  We're using the standard mechanism of the _delete parameter and a checkbox, etc.  So far, so typical.
 
In order to optimize searching and so on, we keep track of the lowest and highest rates from the fares in the deal record (i.e. we denormalize these values).  To determine these low and high rates, we use an ActiveRecord callback to compute them.  This is where the problems come in, at least when using nested attribute support.  Deletion of records from the association (Fares) does not occur until after the Deal record is saved.  What that means is that you can't calculate the low and high rates safely in a before_save callback, you need to use after_save.  That is a bit of a pain in that it means you instantly are doing more DB calls to update those values since you can't do it as part of the primary update.  For us, the rate of writes is small, so that isn't a big deal.
 
Now the second problem of course is that when you do update those values, you're going to cause another save of the record, and that will kick off the callbacks again.  You've now created an infinite loop.  There's no way that I know of, in Rails 2.3.x, to do an update without callbacks (older versions of Rails had update_without_callbacks).  As per the Rails Guide, there are however a few methods that skip callbacks.  One of those is update_all.  It's a bit of a brute force approach, but it is the solution I wound up with, at least for skipping callbacks.
 
The third problem is that within your after_save callback, your association won't be up to date if a deletion has been performed (it'll still contain the item that is marked for delete).  This makes sense, given you are still working with the same instance of your primary object.  Luckily you can just call reload on that.  If we put all these things together, the final solution is relatively simple, although still feels a bit hacky:
 
class Deal < ActiveRecord::Base
  has_many :fares
  
  accepts_nested_attributes_for :fares
  
  before_validation_on_create :create_lowest_and_highest_rates
  after_update :update_lowest_and_highest_rates
 
  ...
 
  protected
 
  def update_lowest_and_highest_rates
    fares.reload
 
    low, high = (fares.minmax_by {|fare| fare.rate}).map(&:rate)
 
    Deal.update_all({:lowest_rate => low, :highest_rate => high},
                    ['id = ?', self.id])
  end
end
 
There are some downsides, such as validations not getting called on the denormalized values when doing the update_all.  You also likely need a before_validation_on_create to do the same functionality (if you have validations for the denormalized values) when first creating your Deal, in which case you don't have to worry about the delete situation.  I'd love to hear of a better solution.  Also, there is the without_callbacks gem that provides some really nice syntactic sugar for this kind of thing, but hasn't been updated since 2008, and looks like it may not work with the latest versions of Rails.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Mon, 01 Mar 2010 08:04:40 -0800 My Espresso Consumption for February 2010 http://cobaltedge.com/my-espresso-consumption-for-february-2010 http://cobaltedge.com/my-espresso-consumption-for-february-2010 James Hoffman's similar post inspired me to track my more simple espresso/coffee consumption for the month of February.  As the following graphic shows, I drink primarily straight shots of espresso, averaging 2.5 shots per day, followed by moka pot, then macchiatos (which are typically what I'll have at a good cafe), etc.  I have 3.13 espresso drinks total per day on average.

Media_httpimgskitchco_cczyf

Media_httpimgskitchco_gilpx

The numbers are a hair low, as I didn't track any data on Feb 7th for whatever reason.  As you may be able to tell, I used Daytum to track it.  In particular I did a lot of data entry via the mobile version of their web site via my iPhone.  Handy.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Fri, 29 Jan 2010 15:43:00 -0800 Rails Action Caching With Query Parameters http://cobaltedge.com/rails-action-caching-with-query-parameters http://cobaltedge.com/rails-action-caching-with-query-parameters
First, if this is known to people, great, if not I hope it helps others, as I wasn't able to find this in all the Googling I did.  Furthermore, since this turned out to be such a simple solution, I'm curious if there are holes...

I wanted to setup more significant caching for some heavy use types of pages on DealBase.  Various things have made this challenging to date, but the last thing I ran into was dealing with the fact that query parameters change page results (duh), but that of course Rails' page and action caching ignore query parameters.  There isn't an easy (or?) way to get around the page caching part unless you start mucking with Nginx rules as well I think.  But, action caching has a solution.  I had done a ton of Googling on this, and I knew about adjusting the cache_path, as well as some other bits, but we have cases where there are a lot of parameters.  Plus, I didn't want to worry about what happens if I add a new search/filter type of parameter later on, and having to remember to add that to the list of things the cache_path differed on.  

As it turns out, you can simply do regular action caching, with full query parameter support, very easily with:

caches_action :my_action, :cache_path => Proc.new { |controller| controller.params }

That will do the regular style of action caching, but stick all your query parameters on (in alphabetical order so you don't have to worry about different query parameter order not retrieving the same cache results).  Now, it's quite likely that you'll want something a bit fancier.  For example, here's something closer to what I use in reality:

caches_action :action_one, :action_two,
  :cache_path => Proc.new { |c| c.params.delete_if { |k,v| k.starts_with?('utm_') } },
  :expires_in => 4.hours,
  :unless => Proc.new { |c| c.request.xml_http_request? || c.send(:current_user).try(:admin?) }

This just adds in some conditions, as well as removes some query parameters that I don't want to differentiate the cache on ("utm" keywords for Google Analytics, etc.).  In this particular case we're not caching the page at all if it's an AJAX request or for our admins.  

Finally, one comment is that you do need to be careful with things like pagination.  In many cases, page 1 is going to get viewed a ton, and maybe page 2, or page 17 for that matter are rarely viewed.  You could have a case where you make updates to the content that then makes a change such that the different pages are out of sync and thus you have duplicate items on pages or missing items.  You could skip using expires_in, and use cache sweepers if that works for you, but factor in how often updates are happening and whether that might nullify the advantage of caching (i.e. if you do frequent updates, it'd expire your cache a lot and maybe too often to benefit from it if you have high rate of updates).

What say you?  Anyone else doing this, any other issues?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Tue, 19 Jan 2010 00:44:00 -0800 Evaluating RubyMine IDE for Rails Development http://cobaltedge.com/evaluating-rubymine-ide-for-rails-development http://cobaltedge.com/evaluating-rubymine-ide-for-rails-development

I have spent roughly the last month using the RubyMine IDE for about 80%+ of my daily development work.  I initially grabbed it to try out the debugger on a particularly nasty problem, and then decided to give it a real evaluation.  My daily work is on DealBase, and covers the full spectrum of Rails development.  The testing was done mostly using a quad-core Mac Pro with 8GB of RAM and 30" and 24" monitors (dual monitor setup), with RubyMine running essentially full screen on the 30".  I also did some work on my MacBook Pro (Core 2 Duo, 4GB RAM).  Both machines use Snow Leopard.  My current and longtime editor has been TextMate, although I have far more time spent historically in environments like Visual C++/Studio, IDEA, a bit of time in Eclipse, a bit in Emacs, BBEdit, CodeWarrior, regularly use Vim, etc.  To date, the speed and light weight of TextMate, combined with it's slick column editing feature (that's one killer feature), have kept me from switching.  But, there may be some movement here...

I kept notes during my eval, and simply broke it down into pros and cons for me, along with a list of "other" comments.  Just going to dump these here, and then I'll tell you the outcome at the end...

Pros
  • Debugger, oh, to have a real debugger back, is quite nice.  This is what motivated me to try it to begin with.  Super easy to setup and get working to, basically no effort at all, which is much appreciated (but do need to see if can be done with Passenger setup instead of Mongrel, since we don't use Mongrel).  I've used command line ruby debugger, but once you've used a solid GUI debugger, the command line ones are just such an inferior way to work.
  • Really like how it puts the folder name in front of the file name when there are multiple files in the project with that name
  • Puts squiggles under misspellings or other code errors - quite handy.  It also puts this under the file's name in its tab, so you can quickly see which files you have open that have errors in them.
  • Hold Cmd while hovering over the name of a partial or similar, and then click to open that file
  • Word selection via double click includes the "@" on field names for Ruby code
  • It's quite smart about correlating Cucumber step statements to their definitions: it will actually show you a step statement doesn't match when that non-match is because the regex in your definition is not matching.  For example, if you had something like  "from (\w+ airport)" in your definition, but you put "from San Francisco airport", it wouldn't match, and RubyMine figures this out (I'm impressed!)
  • Having an irb or script/console REPL avail right there is quite nice.  I'm still experimenting with whether I organize my windows such that this is always at the front or not.
  • I'm just starting to get used to using them, but the "view for" and "action for" little markers in the gutter of controller/view files will take you to the corresponding view/action, a nicety.
Cons
  • TextMate bindings didn't map Cmd-Enter the way TextMate did.  Remapped it and it works fine now.
  • Doesn't work (well) with MacOS X Spaces - prevents switching to another space when you select another app
  • Sometimes grinds to a halt while it re-parses your project or what not
  • File tabs: 
    • They go to multiple rows too easily.
    • They just don't look right/good.  I'm not sure if it's because they're non-native tabs or what.
    • I understand, but don't like how the rows swap when you change to a different tabs.  You lose track of where a file is in the tabs.
  • You can't really just open up an empty, new window at whim.  I use this a lot as a scratch pad type of thing in TextMate.
  • Find in project is nowhere near as fast, or presented as usefully as Ack in Project for TextMate.  It does provide more options, such as filtering files by directory or type and so on, but the speed is generally far more important.
  • Too slow on a MacBook Pro 2.4GHz Intel Core 2 Duo with 4GB RAM - too many operations seemed to bring it (and my machine) to its knees.  Seems ok on my quad-core tower with 8GB RAM.
  • GoTo File (Cmd-T in TextMate) is odd in that it'll match to image files.  I would expect these to be automatically culled out (they are in TextMate), as I'm not looking to open some PNG file for editing.
  • Also seems to crash enough that it bothers me.  I can tolerate an occasional crash, although with TextMate I've run it for weeks on end with no crash, using it constantly.  I've had several either hangs or crashes with RubyMine in the short couple weeks I've been trying it out.
  • Can't run parallel specs/cucumber in it and get the proper processing/handling.  Our test suite is extensive enough, or well, takes long enough to run, that I really need to take advantage of multi-core machines and run this stuff in parallel.  It'd be awesome if they could integrate parallel specs.
  • "Synchronize files on frame activation" doesn't work, or doesn't do what I thought: have to tell it to reload log files from disk.  Even closing the tab for the file, and re-opening it, doesn't re-synchronize it from disk.  This really sucks when viewing log files, and is not even good for regular files - prompt me if the file changes on disk and see what I want to do, before I've spent a lot of time editing something only to realize I was editing a stale version.  
  • Has Google Chrome browser listed in Web Browsers prefs, but I can't select it or type in its location, etc.
  • Has the usual Java UI ugliness - Java file dialogs instead of native dialogs (and thus you see files and stuff you wouldn't normally see - not all bad, but ugly), just doesn't look nearly as good as a native app.
  • If I specify WebKit as my browser (which gets opened when starting to debug), a) it doesn't bring it to front, and b) it gets the URL wrong.  I see this in the address bar: "file:///Applications/RubyMine%202.0.app/bin/http:/0.0.0.0:3000"  I fared better with Chrome, but it launches a second instance of Chrome (not just a separate window, an actual separate app process).  This may be a Chrome behavior though?
  • I added a Tool for "/bin/zsh -i" to have just a regular shell in side, but the coloring and various escape codes and such don't work, and that winds up breaking enough stuff for me (that I don't want to re-jigger for this), that that's a downer.  I'd hoped that I could sort of just "live" in the IDE, like many Emacs users do.
Other 
  • Column editing is partly there, but not as good as TextMate.  If you make a column selection, and then hit paste, it doesn't replace it, it just inserts your paste at the end.  This makes it hard to say bulk rename something that's aligned vertically.
  • The refactoring bits were just ok.  This is a really hard feature in general though.  Simple refactorings I used, like renaming a method worked fine.  But, changing the name of a model class did about 1/4 of the work needed and was questionable as to whether it was an advantage over just doing it all myself.  It got all the obvious, low-hanging fruit, but it seemed to completely ignore Rails helpers and views.  It misses a bunch of things that I'm not surprised at of course, such as table names in SQL conditions (e.g. in named_scopes), model name used anywhere in JavaScript or CSS (which isn't uncommon in Rails code), and then the one that I'd like to see it do a better job on, but that is hard of course is on associations.  So, in my application, I was refactoring our "Deal" model to be "HotelDeal".  We have a "Hotel" model and it has_many deals.  Thus in the code you'd routinely see things like "hotel.deals" to reference that association.  It didn't handle any of those.  Not surprising, but starts to devalue the refactoring feature.
  • Their TextMate keybindings don't get Cmd-Enter right, but you can fix it.  You can remap the keys for "Split Line" and "Start New Line" (swap the two for example - "Start New Line" is the one you want to be Cmd-Enter).
  • I'm not quite willing to call this a con, but I find that I still prefer to use GitX to review and commit my code, instead of what's built in to RubyMine.  GitX has a nicer UI for it, just seems more straightforward, etc.  But, it is at least quite nice to have Git support right in RubyMine.  The two key changes I'd like to see that would potentially fix this for me, would be to show diffs by simply selecting one of the changed files (just like GitX does).  This is key for me because I review all code changes prior to a commit.  Second would be to show what branch I'm on.  I always work on a branch, and it's nice to see the branch as a double-check prior to committing.
  • Hoping for a TextMate theme importer (I think that's coming?), so I can import my customized Argonaut theme.

Verdict?

So, what's the upshot?  Well, I certainly won't ditch TextMate, but to my own surprise, I find I'm getting quite comfy in RubyMine.  When you need the debugger, it's really nice to have, and the other thing that's really been growing on me is their syntax checking - the squiggly lines under misspelled variable or method names, or simple syntax errors, etc.  It just saves time.  Log file viewing is clearly a problem, so I use TextMate for that (or just tail it, depending on my needs), and I don't find it to really be usable on my MacBook Pro, mainly just feels to sluggish, but I don't often use that for heavy dev work anyway.  I'd like to see it (or the debugger) work better with launching non-standard browsers.  I had had the hope that it could be like Emacs is for some folks, where I could really do darn near all my development things from inside it.  You could, but they aren't up to the same level as the separate bits yet (real zsh shell and GitX, in particular).  

My expectation is that I will buy a license, as the $99 price is worth it just to have the debugger when needed, but I might actually wind up using it regularly.  I think their pricing is actually a bit low, but it no doubt hits a sweet spot that likely motivates more folks to buy it.  My experience has been better than expected (I thought I was done with IDE's), and I'm also now eagerly awaiting Aptana's release of RadRails 3.  Their little sneak preview videos have been very promising.  But, I generally hate Eclipse (I've had plenty of time with it back when doing Java work, and always preferred IDEA, so there's my bias out in the open), so I'm wondering how that'll impact things.

Thus, I'd suggest that if you're a Rails developer, you give RubyMine a whirl.  It's really pretty impressive and I look forward to trying it a bit more, and also seeing what improvements come in the future.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 14 Jan 2010 08:21:47 -0800 Liberation by Boxcar: or Alternatives to Twitter SMS http://cobaltedge.com/liberation-by-boxcar-or-alternatives-to-twitt http://cobaltedge.com/liberation-by-boxcar-or-alternatives-to-twitt The iPhone app Boxcar has liberated my iPhone from the stress and worry caused by Twitter SMS.  What? 

All of the server monitors I have setup, but most importantly, the ones for DealBase, will send me an SMS if there's a problem.  I also get Hoptoad exception notifications via SMS for DealBase.  These are things that are timely, and important.  I'd had one bad case where the servers were reporting down (they weren't actually, was a DNS issue), and this wound up unfortunately setting me up to be hyper-vigilant in checking SMS.  Unfortunate stress and worry.

However, what compounded this was that I was getting some tweets (friends mostly) via SMS.  Well, obviously, the tweets far outnumbered any actual server issues, but due to the above vigilance about checking SMS's, these tweets would make my phone ding and make me immediately worry, "did the server go down?!"  I wound up starting to cut down whose tweets got sent via SMS.  But during this, I also realized that I actually didn't want any tweets via SMS unless they were a "direct" or a "mention".  If they weren't, I'd just read them when going through my regular Twitter feed.  However, Twitter doesn't have an option for just getting any directs or mentions via SMS (they really should).  That led to Boxcar...

Boxcar is a fantastic iPhone app that monitors your Twitter (or Facebook, and other things) stream for directs or mentions, and sends you push notifications when one is found.  It's fast, staying extremely current with your feed, and works great.  With this addition, I've been able to off SMS for everyone I follow on Twitter.  I've been doing this now for about a week, and realized this morning how liberating it has been!  

Normally, I would wake up, instantly check my phone (which serves as my nightstand alarm clock now, thanks to the excellent Kensington Nightstand Charging Dock - click the little photo icon to see how it'll look in use), to see if any server down SMS messages came in that I didn't hear while sleeping.  Usually I'd have a few SMS messages, which would instantly raise my stress level, only to pretty much always find they were tweets.  With Boxcar, now my mornings are great.  I still check my phone of course, but yep, no SMS's anymore.

So thank you Boxcar, great product!  While I can't more heartily recommend Boxcar, I'll point out Prowl which some folks also recommended.  My main issue with Prowl is that it requires an always on Mac to grab whatever data you want as a push notification, and send it to the Prowl servers.  There are workarounds for some things for this, but it was just way more hassle and such than I wanted, for what I needed.  But, you may find it useful if you have data you want as a push notification that you don't have another way to get.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Wed, 06 Jan 2010 16:29:00 -0800 Workaround for jQuery Autocomplete Plugin mustMatch Fail on Commas http://cobaltedge.com/workaround-for-jquery-autocomplete-plugin-mus http://cobaltedge.com/workaround-for-jquery-autocomplete-plugin-mus

The jQuery autocomplete plugin is quite nice, and we use it a fair bit on DealBase.  However, what I found was that if you set the mustMatch option, your text cannot contain commas, colons, and a few other punctuation (and maybe other) characters.  For some reason that I've yet to track down (debugging through many nested anonymous functions and callbacks has yet to yield an answer), it thinks it changes at some point to not think it's a match. A good example of this is if you allow a user to type in a city name, but you want to show them matching cities with the state and/or country included, to disambiguation.  E.g. you may have Portland, Oregon and Portland, Maine (not to mention the few Portlands in Australia :)

What I found fixed it for me was to set the matchSubset option to true.  This allowed it through, retaining the full text of something like "Portland, Oregon".  According to the plugin's docs, matchSubset should only come into play when using the cache, which we don't use (because we limit results to 20 items, and often there are more than 20 matches, e.g. a user types "new" or "las" or something - many cities will match).  

I'd still like to track down the real bug here, but since others have run into this, and I've yet to see any other solutions, I wanted to post that, in hopes it'll help some other person suffering from this.

Update: even setting matchSubset to true, did not solve the problem where you have a dash/hyphen in the string, and the part that matches is to the right of the dash.  Removing the dash is the only thing I've figured out to make it work.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 31 Dec 2009 15:02:00 -0800 Final Thoughts on Coders at Work http://cobaltedge.com/final-thoughts-on-coders-at-work http://cobaltedge.com/final-thoughts-on-coders-at-work

I finished reading Coders at Work about a week ago.  Truly a great book as others have also said.  I was surprised by some of the things I read in the interview with Donald Knuth.  He is such an icon, and his books are really intense, and as such, I think I expected something (someone?) different.  But, he seems quite approachable, down to earth, and of course very interesting as well.  A couple great parts stood out in Knuth's interview.  

When he was asked about the reading of his books and how challenging they can be (due to the math involved, etc.), he responded, "I sometimes wonder if I can read them..."  How awesome is that?!  Later on in the same answer, he says, ..."and I write it down and put it in the book so that I don't have to have it all in my head."  It's nice to know he doesn't necessarily have his books memorized.

In another section, when asked about a technique he's using and whether it'd be useful to others, he answers, "I have no idea.  I'm not sure how it would work if I was in a team of 50 people..."  To me, that's refreshing in this day and age when everyone is so adamant about the methodology or process they use to develop software being the one right way, etc.  One way does not work for everyone.  I've seen this getting a bit out of hand in the Ruby community at times.  There can be a fine line between being very passionate about a technique, and preaching it or, trying to cram it down everyone else's throat as THE way to do it.  I think ideas hold a lot more weight when you can be excited in showing someone something, and then let them absorb it and come to the same realization themselves (or not - even if they don't, they'll probably have more respect for it working for you, instead of being completely turned off).

Lots of other good bits.  One final bit about the book in general that surprised me personally, is that I generally stay away from history.  I just don't generally find it that interesting, and in the software and compute world, often find it not pertinent to work I'm doing.  But this book presented history in a truly enjoyable way.  It has motivated me several times to look into various topics.  I'm currently on a Clojure kick (as I'm motivated to re-learn LISP, as well as see more about functional programming in general (thanks Armstrong and Jones)); and I plan to crack open the Knuth books shortly as well (to date I've been one of those folks who owns them, but they just sit on my shelf).  Listening to various luminaries talk about the non-trivial nature of them, as well as Knuth himself, simply makes them feel more approachable.  

And, I should have a bit more reading time, since I managed to fracture my ankle and tear some ligaments on the 26th while trail running.  So, I'm doing a lot of couch surfing these days.  

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 10 Dec 2009 17:21:00 -0800 Pivotal Tracker GitHub Post-Receive Hook Now Smart About People http://cobaltedge.com/pivotal-tracker-github-post-receive-hook-now http://cobaltedge.com/pivotal-tracker-github-post-receive-hook-now

That title is a bit cryptic, but here's the deal.  In the past, the GitHub post receive hook for Pivotal Tracker (http://github.com/chris/tracker_github_hook) was configured using a single API key.  This meant all the comments it added to Tracker were as the person who corresponded to the API key - regardless of who actually made the commit to git.  On multi-person teams, that sucks, as you want the comment to be from the person making the git commit.  Well, that's fixed now.  The fix is backward compatible, so if you simply update your version, nothing will break.  

To take advantage of the new ability, you need to get the new version of the code, and then update your configuration file to associate the Pivotal Tracker API token of each person who may make a commit with their git email address.  To do so, add a new user_api_tokens value to the configuration file, listing each person (arbitrary name) and their API token and email address.  The email address needs to match that which is associated with their git/GitHub commits.  Here's an example:
user_api_tokens:
  chris:
    email: 'chris@example.com'
    tracker_api_token: deadbeef340e3bafa96f5b2cac6986ed
  zach:
    email: 'zach@example.com'
    tracker_api_token: badd00d27202feed12de3120903ea83a

Now what will happen is that anytime a commit comes into the post-recieve hook, it'll try to correlate the email of the author of the commit with an entry in user_api_tokens, and if found, it'll use that tracker_api_token to call the Pivotal API, and thus associate the comment in Tracker with the person whose API token it is.

For any email that isn't found, the default/top level tracker_api_token will be used (this can be the same as one of the user_api_tokens), so you still want to keep that one in there as your default API token.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 03 Dec 2009 14:21:00 -0800 Coders at Work is a Great Book http://cobaltedge.com/coders-at-work-is-a-great-book http://cobaltedge.com/coders-at-work-is-a-great-book

I'm now about 3/4 of the way through Coders at Work, which is a series of interviews with software lumninaries (a good range, like Douglas Crockford, Donald Knuth, Brad Fitzpatrick, etc.).  I've been truly enjoying this book, one of the better computer/software/geek books I've read in a while.  There have been various points of debate further covered by Lambda and so on; big ones tend to be C++ hate and testing.  I've liked reading a lot of the different points of view on what one needs to know to be a great programmer, as well as debugging techniques (a lot more print statement use than I expected!).  

Since I just finished the chapter with Dan Ingalls, a couple points that caught my attention:

He's never used C or C++.  For someone with his experience, it caught me by surprise.  My biased view of things is that C is that "everyone" has done C.  I realize these days that's very much not true, in that you have plenty of folks who've only used PHP for example.  But, if you've got say 10+ years of experience, it's amazing if you've avoided C (or C++).  I suspect it will still be some time before I've written more LOC in a language other than C/C++ (for me, more C++ than pure C).  

And, this question and answer, to quote directly from the book, I loved.  Not because it means we keep programming to us programmers, but because he nails the fact that people want to focus on what interests them, and collaborating so that you leverage your expertise and don't waste your time on something that someone else can do more efficiently and/or effectively, is great.  Oh, and I love the last sentence in his answer, awesome:

Seibel: Related to that, as more and more fields rely on computing in more and more ad hoc ways, there are folks who want to find a way for "nonprogrammers" to program.  Do you think that'll happen, or will domain experts, say biologists, always have to team up with programmers to build custom software to solve their problems?

Ingalls:  I think there will be that kind of collaboration because the biologist isn't interested in programming it.  He's interested in finding out this or that.  Then there's somebody who understands how this stuff is being wored on on the computers who can help him do that.  I think the thing that lets a nonprogrammer program is an application. 

 Get the book, it's good stuff.  A few notes about me, in relation to common themes:
  • I like testing, and believe in automated test suites, etc.  I like TDD, BDD, and TFD, etc., but I'm not insanely strict about it either.
  • I've done a ton of C++ (e.g. Photoshop and other desktop apps), and at this point, especially after things like templates and so on, find it repulsive.
  • I don't believe you have to know the hardware or assembly language to be a great coder - unless what you're coding is particularly impacted by that.  Ingalls talks about this a bit too.
Oh, one last thing the book has inspired, or really, has further motivated me on, is to [re]learn some other, what I'd consider non-mainstream languages (depends on your POV).  In particular Lisp, or in my case, I'm poking around with Clojure (I did scheme stuff in school, and loved it, but it's been a long time since I've done any lisp or scheme code, nor have I written a significant app/program with it) and Simon Peyton Jones' interview inspired me to look at Haskell.  I've been quite interested in functional programming in general lately.  I've spent some time with an Erlang book, but honestly the syntax just repulsed me and thus I'd rather look at something else (Armstrong's interview was also interesting, not that any of them weren't).  I'm after the functional stuff more for the principles they pursue, and don't really expect to use them specifically, so I'd rather spend time with one where the syntax is more appealing.  Fun.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 08 Oct 2009 19:01:31 -0700 Switching to Posterous http://cobaltedge.com/switching-to-posterous-4 http://cobaltedge.com/switching-to-posterous-4 I'm moving my blog to Posterous, or at least trying it out.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Fri, 02 Oct 2009 02:25:00 -0700 DealBase Now With RSS Feeds For Hotel Deals http://cobaltedge.com/dealbase-now-with-rss-feeds-for-hotel-deals http://cobaltedge.com/dealbase-now-with-rss-feeds-for-hotel-deals I've been extremely busy with DealBase work, so have lagged on blogging, but have some interesting things coming up and hope to post more soon. Recently I added RSS feeds to all of the city/destination and hotel pages on DealBase. This is just one more way for you to keep up to date with all the deals we add to the system. Our other primary way, aside from browsing the site of course, is to sign up for personalized alert emails. This lets you follow one or more cities, and set criteria like class of hotel (i.e. you only want to see 4 and 5 star hotels), maximum price, and so on. You can set a schedule for how often you want the emails (once a week, twice a week, daily, etc.). We'll send you up to the best 10 deals that match your criteria. You can also simply subscribe by just supplying your email address and nothing else and we'll set your initial preferences for our top 10 destinations. We'll continue to enhance this alert service, and I'd love to hear any suggestions people have for additions, changes, etc.

Development of the alert emails has been interesting. One of the most useful tools throughout has been Litmus' email testing service. It's pretty slick. They cover quite an array of email clients, both web hosted (Gmail, Yahoo, Hotmail, etc.), as well as desktop (Outlook, Apple Mail, Notes, etc.). They also do spam testing. When you begin a test, they supply you an email address specific for that particular test run, and then you just email them the real email you want tested. You can also paste in an email, but I prefer to do the sending approach to as closely mimic the real thing as possible. I have my IRB and various other bits configured to make it a single command to fire off test cases to a Litmus supplied email address, and the whole process works great, and is truly worth Litmus' cost.

I started off mentioning RSS, and back to that... The RSS does work differently than the email alerts (obviously), and to some degree the web page. It is like selecting the "Most Recently Posted" sort on a page (see below image). Deals are supplied to the RSS feed as they're posted, just like a blog would do. Just one more way to stay on top of deals. Oh, and don't forget we're on Twitter too.

Media_httpimgskitchcom20091002pqjtqxxmjkjwiw3nutt1e9ui77previewjpg_gwcdjfncnewsazk

Uploaded with plasq's Skitch!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Thu, 20 Aug 2009 07:28:00 -0700 Further Continuous Integration travels: Hudson, and Back to Integrity http://cobaltedge.com/further-continuous-integration-travels-hudson http://cobaltedge.com/further-continuous-integration-travels-hudson [Update: I resolved the Git issue, and have now switched to using Hudson. The advantages of it's in-progress display, ability to more closely monitor and/or kill a build, and my impression of it being more stable, won the day.]

After switching our CI server to Integrity, there were a few blips, one of which is that we were hitting swap (memory). Hitting swap is not surprising and I'm surprised it hasn't been a problem sooner, since memory is our #1 battle. I figured if I was going to up the memory on our CI server, I might also try Hudson, as that was the main reason for not trying it previously.

The short story is that I tried it, and we're back to Integrity, but I learned some interesting things. The following is both some notes on installation, as well as some reasons why it didn't work out...

Installing Hudson

Our CI box is a slice at Slicehost, running Ubuntu 8.04 LTS, and I'd just upped it from 256MB RAM to 1GB. Also of note, I've built and install Git 1.6.4 for this system. The following are brief notes on getting Hudson going as it wasn't quite as simple as most folks made it out to be...

First, I followed the directions on the Hudson site for installing Hudson from the Ubuntu package. This amounts to adding the package repository, updating apt-get, and then doing:

sudo apt-get install hudson

This installs all the Java 1.6 stuff you need (and mine seems fine with 64bit Java), and other dependencies. After the install, Hudson is running, on default port 8080. Next up I added a server block/configuration in Nginx for Hudson (and unlinked/removed Integrity). I then went to Hudson in my browser. What I got was an error message about the xstream library. Fixing that was easy, as it turned out: downloaded the latest (1.320 at the time) hudson.war from the Hudson site, and replaced /usr/share/hudson/hudson.war with it. Restarted Hudson, and voila, now it was up and running.

Also, Hudson runs as the user "hudson", so I needed to add an SSH key for that user, and then add the public key to GitHub. And, setup a ~hudson/.gitconfig as needed. Finally, as I found later, do a git clone or an SSH to github so that you get past the whole SSH authenticity question when you first SSH to an unknown server. Note, the Hudson user is not an interactive user, i.e. you can't directly login as that user, so to gen the SSH key, you'll need do something like su to root and do, sudo -u hudson ssh-keygen -t dsa.

Configuring Hudson

Before adding a project, I needed to config some plugins. I went to the Manage page, clicked on Installed, and turned off the Subversion plugin and restarted. Next was going back in to manage plugins, and installing the Git, Github, and Rake plugins, and again restarting. Both restarts showed an Nginx bad gateway error, but simply refreshing got it back (probably just needed more time for Hudson to restart).

Then to configure a build, from the main Hudson page after a fresh install, click the "create new jobs" link. In the ensuing form, enter a project name, and select "Build a free-style software project".

Next:


  • checked "Discard Old Builds" which then shows you options (so you can put in keep for X days, or X number of builds)

  • Added URL for Github project, http://github.com/yourproject/yourproject

  • Select Git as the SCM, and entered by git@github.com:yourproject/yourproject.git URL for the repository

  • Turned on merge after build option. This will supposedly add tags for the build to your code base and then merge them back in. More on this in a bit.

  • Next I configured the build steps for my project. All I really did here was take the same build steps I used for Integrity, and added them as individual shell and rake tasks.

At this point, I fired off a build (truth be told, I started with just a single build step to vet it), and things worked, with the exception of the very last step, where I push the Git tags back to GitHub. This is what I saw:

[workspace] $ /bin/sh -xe /tmp/hudson1444107192962944065.sh+ /usr/bin/git push --tagsXML error: syntax errorerror: Error: no DAV locking support on https://github.com/dealbase/dealbase/error: failed to push some refs to 'https://github.com/dealbase/dealbase'

I've now been searching for answers to this, and haven't yielded anything. I've tried the git push directly from a shell, with the same result. If I do this as a different user (e.g. under my user) it works fine. This git push is attempted both as part of a rake task (the ci_tag task), as well as I tried making it just a straight shell command in Hudson.

After a lot of googling, and asking, and no resolution in sight, I've gone back to Integrity...

Comparisons and Notes

First off, I think Hudson looks pretty stellar. There are a TON of plugins for it, and it seems quite mature and polished. The essentially 100% configuration via the GUI is slick. Install, despite a few hoops above, was actually pretty painless. So, here's just a few notes/opinions:

Hudson



  • You will need some memory to run Hudson, more than with Integrity or CruiseControl.rb. From what I can tell, you probably want a system with 1GB or more. Various other folks I talked to all had 2GB or more systems, and their Hudson processes were taking 1.5GB or more. This is partly just a Java thing. It should be noted, the others were running more than one build with Hudson, and mine seemed to work fine on a 1GB total memory system (didn't seem to hit swap).

  • Hudson allows you to kill a build while it's running (nice!).

  • Hudson works with CCMenu/CCTray out of the box.

  • The git integration has more options in terms of picking branches, doing merging, and various more involved operations, but doesn't have GitHub post-receive hook support out of the box (there are plugins up on GitHub for it, but not listed in the standard plugin list).

  • Hudson runs as user "hudson", which is a user that has no shell. You could change this, although the idea is you shouldn't have to. However, this complicates setting up SSH keys and various things. And, of course, I had the issue with Git as mentioned above. I could probably change this to run as my user and so on, but part of all this for me is not having to change a lot of defaults and start messing with core configurations/designs of the system. In part, I just don't have time to do that, and to maintain it (these kinds of changes often cause problems when you upgrade versions, etc. - also known as you may forget to redo these changes if an upgrade undoes them :).

  • The UI and web app itself is quite nice, understandable, well done in general for something like this.

Also, thanks to the Tea-Driven blog for motivating me to try Hudson (and for some tips on Testjour - more on that in another post).

Integrity

I really only have one main complaint about Integrity, and that has to do with indication of a build in progress. It essentially doesn't indicate it - it says it hasn't been built yet, but a build may actually be running. The CCMenu/integritray plugin will show you that a build is running, so this mostly solves my problem, but this seems like a core failure. I may have to look at fixing this. And that is a win for Integrity in that it's Ruby, and thus I'll be more apt to go fix this (while I spent MANY years doing heavy Java work, I don't have interest in working in that code anymore for a task like this).

CruiseControl.rb

One thing that remains an advantage for CC.rb is that it has "build artifacts" - i.e. you can create files and such as part of your build and have those known to CC.rb, where it then links to them in the summary of your build. You may or may not need it, but it's also very handy for simply showing you the Git tag you created on a successful build. I just touch a file in the build artifacts dir with the name of the Git tag, and then I don't have to dig through the output of the build to find my Git tag.

That's all the time I have for today, hopefully this is also helpful to others...

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Mon, 17 Aug 2009 09:09:00 -0700 Setting up Integrity for Continuous Integration http://cobaltedge.com/setting-up-integrity-for-continuous-integrati http://cobaltedge.com/setting-up-integrity-for-continuous-integrati Recently I switched the DealBase continuous integration server to use Integrity instead of CruiseControl.rb. This happened because I'd been having some sporadic failures under CC.rb that didn't seem explainable (no code would change, and tests would fail at random), and also due to some changes in Cucumber between versions, it all conspired to switch.

It should be noted that, as you might guess, the "random" failures were not exactly random, but suffice it to say that the root cause re-inforced my notion to switch. My main beef with CC.rb has more to do with it being somewhat in bed with Rake and wanting to run your CI build via a rake task, and some of the issues (or impurities?) that come up with that. But I'm boring you...

Anyway, Integrity... Setup is relatively easy, and is covered fairly well on their setup page/docs. But the following is what I did, which I'm documenting for myself and anyone else who may find it useful.

I setup my server to use with Nginx and Passenger. I tried using Integrity with Nginx and Thin, but wasn't able to get Integrity to work right (similar to the results defunkt had when they tried it at GitHub). We've standardized on Nginx+Passenger, so this was good anyway. I nuked the Nginx I had already and proceeded (all this being done on an Ubuntu Hardy VPS system at Slicehost):

sudo gem install passengersudo passenger-install-nginx-module

I let it install Nginx, and picked the default location. I then re-added our HTTP Basic Authentication and a few other Nginx tweaks as I had in the prior Nginx configuration. Next up was to install some prerequisites and Integrity itself:

sudo apt-get sqlite3 libsqlite3-devsudo gem install integrity do_sqlite3 thinintegrity install /home/ci/integrity --passengercd integrity

Next you'll want to tweak config.yml to customize the domain where you'll access your CI server. I left the rest the same. Then setup Integrity's database:

integrity migrate_db /home/ci/integrity/config.yml

I also added the "integritray" plugin, so that I could continue to use CCMenu to monitor my builds. See the integritray GitHub page for simple install.

Now point Nginx/Passenger at your install, by adding the appropriate server block for a Passenger Rails app, such as:

server {    listen       80;    server_name  your.ciserver.com;    root /home/ci/integrity/public;    passenger_enabled on;    auth_basic            "Restricted";    auth_basic_user_file  /opt/nginx/conf/htpasswd;}

Finally, fire up Nginx, and surf to your CI server domain/URL. You should see something like this:

Media_httpimgskitchcom20090817gdy8kwxgfd9uf7dxx7arxauqh1previewjpg_kqbjjrenpstnenf

Uploaded with plasq's Skitch!

Click the "create your first project" link, and enter details about your app. The "Git repository" field should get your GitHub or other git server URL (e.g. your clone URL). For a build script, the following is what I used:

rake log:clear && RAILS_ENV=test rake db:reset && spec --options spec/spec.opts spec/**/*_spec.rb && RAILS_ENV=cucumber rake db:reset && cucumber --strict -q --format pretty features && rake ci_tag

This is one nice thing about Integrity - it's pretty much any command you can give it. Sure, you might want to wrap that up in a Rake task, or a shell script or however you want to do it. I just entered that raw so it's overly obvious exactly what it's doing. I also found this to work better than doing it as a Rake task, as somehow I wasn't getting the environment to switch properly under Rake. The "ci_tag" rake task is my task for tagging/labeling succesful builds in Git, etc.

Next, you'll want to setup a post-commit service hook on GitHub. You can get your Push URL by clicking the edit link for your project in Integiry:

Media_httpimgskitchcom20090817du9damc7t9xww4kje1pusq4tqkpreviewjpg_eczbgxicmvskhem

Uploaded with plasq's Skitch!

Note, that works even with HTTP Basic Auth, just add your user credentials to the Push URL before pasting it in on GitHub.

Finally, fire off a build. And note, one downside of Integrity is that it doesn't indicate (in the web UI) that a build is underway. It just says it hasn't been built yet. The integritray item and thus CCMenu will show you that it's building though.

Lastly... some have asked why not XYZ CI server? A few notes on this:


  • Hudson: this looks awesome, but also somewhat overkill for our needs. I have one project to build, and I'm doing it on a very inexpensive slice that has only 256MB of RAM - I doubt I could even start Hudson in that little RAM, being it's a Java web app, etc. Secondarily, I'd prefer to have the app be Ruby so I can hack on it (I've made at least very minor tweaks to every CI server I've used to date).

  • cruisecontrol.rb - this is what we were using, and it worked well, with minor exception to some random failures and the Rake-oriented build process. I'd really say this is minor though, and would suggest folks try it out. You can of course refer to my previous writeup on setting up CruiseControl.rb :)

  • CI Joe/cijoe - this is actually what I started with when I looked at exploring alternatives. I had problems getting the build working properly, which seems odd. In hindsight that may have wound up being due to some problems during our switch to a newer version of Cucumber. But, one thing I didn't like is that there is no state maintained, so if you stop and start cijoe, it loses track of all its previous builds. This may or may not matter much to you, but I didn't like that. I also didn't want to spend time writing notifiers/CCMenu integration type stuff for our needs. I will ay that cijoe setup/install is pretty cool.

  • Run Code Run doesn't have a viable plan for us yet, plus I've heard having it run custom rake tasks and such doesn't work (wrong?). Furthermore, I didn't really want our private code on their servers and didn't see a need to outsource this.

  • others... either hadn't heard of them, they didn't work well with Rails, or whatever - upshot, Integrity worked, got it up and running fairly fast, and didn't need to spend any more time on this.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Tue, 16 Jun 2009 06:51:00 -0700 Moving Further Into the Cloud http://cobaltedge.com/moving-further-into-the-cloud http://cobaltedge.com/moving-further-into-the-cloud A little bit ago, I went back to using multiple computers again. For a while I'd just done everything with a MacBook Pro, which was nice - only a single machine to maintain, always had everything in one spot. But alas, twas time for more performance, so I got a Mac Pro, which is now my primary work machine, with the laptop relegated to basically iCal and Things for the bulk of the day (as my 3rd monitor), and then any portable needs, or working on the couch or deck, etc.

Anyway, my main thing against multiple machines, after having spent many years with anywhere between 2 and 5 machines (mostly while working for Adobe), was the maintenance and synchronization of those machines. So, now that I'm back to 2, I am back to wanting/needing my data on whatever computer I'm using. These days this also really extends to my iPhone to some degree as well. It's my truly portable computer. So, with all the "cloud" computing/services these days, this is to some degree easier. I'm not that big a fan of Google having all my data, but I will use the services that are the best in class, or best for my needs, and no doubt some of that is Google, but there are many others.

I have not gotten all my data truly available on all the computers I want it on, or as well as I'd like yet, but I'm getting closer. Also, I agree with Al3x in that if the data is important, only having it on a free cloud service is not wise. I haven't fully followed that, but that is part of my plan. Here's some notes on what I've done so far...

Email

This one is easy. I use Gmail for all my email accounts (about 15 if you count across various domains and so on). Right off, this is one case where this is the only place my data/email lives, so I'm only solving the accessible from anywhere issue. But, I'm also of the mind that I could pretty much lose all my email and be fine. If there are truly important things in it, that data tends to wind up getting put in somewhere else (EverNote, etc., see below) as appropriate. Gmail is so much better than any other Email. I even use it for some non-traditional things, like all our recipes are stored in a Gmail account. Makes it easy to trade recipes amongst friends and family, great for searching, and again, I can get to it from anywhere I can access the web.

Further, I use MailPlane as my actual mail client. It is a very rare day that I use a web browser to view Gmail. On the iPhone I just use the regular iPhone mail client, which has some drawbacks, but for my needs is ok.

Notes and Misc Data

This is the place that recently changed and has become an outstanding solution. I used to use 37signals Backpack, but now use EverNote. EverNote is really quite amazing. I hadn't noticed the Notebooks before, and that's been a great feature for me to do high level organization. Then, the searching is quite good (and of course Backpack essentially didn't even have searching). But, what really swung this over was their desktop client, web storage, and then iPhone client. This gives me great desktop performance, but then access from any web browser, as well as iPhone, AND I get the data stored locally and off-site (i.e. on the web). Furthermore, it sync's across computers. So, I feel like the data I have here is very safe (since it's in at least 3 places). Even better, this allowed me to stop paying for Backpack (my use of EverNote is nowhere close to their paid account). I don't mind paying for software at all, but I had felt that I wasn't getting the solution I wanted from Backpack, so didn't want to pay for that any longer.

Code

GitHub and Git. Do I need to say more?

Bookmarks

Two things here: .Mac and Delicious. I use Safari as my primary browser, and leverage it's Bookmark Bar for common stuff, so sync that across machines and iPhone with .Mac. Delicious gets all the other bookmarks.

RSS/News Feeds

Another recent change was to stop using NetNewsWire which I've used forever, and switch to Google Reader. Specifically what made this work well was creating a Fluid app with the Helvetireader styling. NNW had sync via NewsGator, but it really just didn't work well. It didn't seem to keep the list of feeds in sync, and then it's sync during feed download just didn't seem to cut it. So now, with the fluid app, and then just plain Reader (via browser) on the iPhone seems to solve this all nicely.

Documents

So far this is a mix of using DropBox and Google Docs. DropBox is awesome for keeping files in sync across machines, and then also available on the web. I've been ramping up my use of DropBox.

Things that Aren't sufficiently solved yet

Calendar and Address Book

Update: I'm now using .Mac to sync Address Book, seems to work great.

I'm using iCal and Address Book. Primarily this is due to the super easy sync with the iPhone. I can sync two computers with BusySync or some other things, but haven't seen a great solution yet, as well as haven't investigated that much. Even with .mac I think you still have to have a primary calendar and you're publishing to the other, etc.

I've used Google Calendar in the past, but didn't like it that much, and part of all this is ensuring sync is brain dead easy and solid. My wife and I sync calendars with BusySync, but that has been spotty. The various Google/iCal sync things I've tried have been iffy in the past. And, the real key is, how well will it sync Google cal to the iPhone calendar? An area I need to learn more about.

Address Book, not sure of my options here either. Sync's nicely with iPhone, and .Mac so far.

Music and Photos

I've yet to see an iTunes sync thing that works really well. We tried TuneRanger but it was not good when dealing with two existing libraries. Also, we have a lot of music, so keeping it backed up on S3 or similar actually starts to cost real money. Of course these days, the primary need for this is to sync to my iPhone. Most of the time at home I'm listening to Pandora or some similar thing. I use Pandora a lot on the iPhone, but I also listen to various podcasts, and then there are times when Pandora isn't feasible (crappy/no signal, or I'm needing to use another app on the phone while listening to music).

These same issues hold true for photos/Lightroom libraries. With Lightroom so far, for each calendar year, I have a Lightroom catalog, and then at the end of those years, I burn DVD's with the photos. Of course, the DVD's are just sitting in our house right now, not in a safe deposit box, etc. (we used to do that, but haven't since we moved to Oregon - lazy). But my bigger concern here is that I'd like my Lightroom library to stay in sync across my two machines, so I can use the burly Mac Pro when working at home, but then have my MBP when on the road.

I guess that's it for now. What solutions do you like? What are people doing for large data (GB's or TB's of music, photos, video, etc.)?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Tue, 12 May 2009 08:01:00 -0700 Passenger Fails to Regenerate Cached/Aggregate Assets for Rails http://cobaltedge.com/passenger-fails-to-regenerate-cachedaggregate http://cobaltedge.com/passenger-fails-to-regenerate-cachedaggregate At DealBase, we've been testing Nginx with Passenger, and have mostly had good results. There are two issues that have come up, hopefully only one of which may broadly affect others.

The first issue, which likely affects anyone using this, is that it appears that if you combine and cache CSS or JavaScript via tags like this in Rails:

<%= stylesheet_link_tag :standard, :cache => 'standard' %>  <%= javascript_include_tag :jquery, :cache => 'jquery_all' %>

The ":standard" and ":jquery" symbols are expansion symbols for multiple CSS/JavaScript files defined in a Rails initializer. On the first request Rails gets, it's supposed to combine all the files as per the expansion symbol definition, and then produce a "cache" file, so you have a single file that is included in your HTML.

This worked fine for us under Mongrel, but it didn't seem to regenerate under Passenger after doing a deploy, even with a restart to Passenger. We had to do a second restart of Passenger, and then hit the server at least twice, if not more to see it get picked up.

Thanks to a tip from Engine Yard, one solution can be found on the overstimulate blog, where they detail how you can add a rake task that you call during deploy to regenerate those cache files. This is really even a nicer solution under Mongrel and others, as it will mean it doesn't occur during your first request.

The second problem seems confined to my MacBook Pro laptop (no problem on my MacPro tower). That is, I simply cannot get Nginx+Passenger to work. It installs fine, Nginx runs, but I get some odd permissions problem from Passenger:

2009/05/12 11:57:52 [alert] 19611#0: could not create /var/folders/7m/7m7ezMSTHdiBHz5bzVyNDE+++TI/-Tmp-//passenger.19596/control_process.pid (13: Permission denied)2009/05/12 12:01:19 [crit] 19611#0: *1 connect() to unix:/var/folders/7m/7m7ezMSTHdiBHz5bzVyNDE+++TI/-Tmp-//passenger.19596/master/helper_server.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: dealbase.dev, request: "GET / HTTP/1.1", upstream: "unix:/var/folders/7m/7m7ezMSTHdiBHz5bzVyNDE+++TI/-Tmp-//passenger.19596/master/helper_server.sock:", host: "dealbase.dev"

The first line of those two lines occurs when I start Nginx. The second happens when I try to surf to a page from my app in my browser (which makes sense given the first error :) If anyone has any suggestions on this one, let me know!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey
Wed, 11 Mar 2009 02:49:00 -0700 Front End Rails Developer Job at DealBase.com http://cobaltedge.com/front-end-rails-developer-job-at-dealbasecom http://cobaltedge.com/front-end-rails-developer-job-at-dealbasecom

At DealBase, we have an opening for a part-time front end Rails developer at DealBase.com. The opening is for US residents only, and for individuals, no agencies or recruiters please. Most likely you'd be working remotely/telecommuting. The job posting, which is posted in several places, such as Rubynow, Working With Rails, and Rubyjobs.in, covers all the details, but I'll relist it here for ease:


DealBase.com, a startup hotel deals site, is looking for a stellar front end web developer who will adapt our current look/feel to new features, leverage JavaScript for useful and fun features, and is eager to apply their skills to enhance the user experience of our site. We're looking for you to share your knowledge and make an impact, be passionate about your work, and up-to-date on the latest technologies. If this is you, and you enjoy working with a small, distributed, agile team, then we'd love to talk with you.

Requirements for this position:



  • Deep knowledge of XHTML and CSS

  • Familiarity with browser capabilities and restrictions for all major browsers

  • Solid JavaScript skills

  • Experience with/demonstrated use of Git

  • You use and demand MacOS X as your primary development environment

  • Comfortable at the command line

  • Basic skills for image editing and optimization for the web

  • Exposure to and basic knowledge of Ruby on Rails

  • Great communication skills

  • Attention to detail

  • Ability to work both independently and on a team

  • Eagerness to share ideas and problem-solve creatively

  • Experience working on consumer oriented web applications/consumer focus

  • Quick learner, and good at digging in to problems

  • Agile development practices

  • You are based in the US.

  • Individuals only (no multi-person firms, agencies, etc.)
  • Nice to have:



    • jQuery experience

    • GitHub experience

    • MySQL experience

    • Use of test frameworks, TDD, and BDD

    • experience with Linux

    • If you'd like to work with us at DealBase.com and think you're a good fit for this position, send us a resume and sample work, or let us know where we can see your resume and work/code, by emailing jobs@dealbase.com. Please note, we are only considering candidates based in the US.


I'm excited to find a great developer to work with. DealBase has been an awesome company and app to work on, and we're already experiencing great success. We have some pretty cool features planned, and it'd be ideal to get some real CSS and JavaScript ninja skills making those features even better. So, if this is you, please do get in touch, making sure to send email to the right email address as outlined in the job description.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/230973/crb_headshot_square_april09.jpg http://posterous.com/users/36UK8zDn5MWJ Christopher Bailey Chris Christopher Bailey