CommonThread - Our Blog

MongoHQ to Host with Engine Yard

Written By: Jason McCay

January 9th, 2010

We are excited to announce that as we approach the end of our beta phase, we have moved MongoHQ to the Engine Yard Cloud. Having already had great success with Engine Yard in the past, the opportunity to partner with this amazing team was welcome and exciting!

Given considerable experience managing (and worrying about) our own servers and hosting arrangements in the past, the Engine Yard Cloud has been a breath of fresh air. From worry-free uptime to painless deployment to easy of scaling to monitoring, Engine Yard really does it all. All this equates to CommonThread being able to provide a reliable product that is speedy and responsive…and that makes happy customers all around.

The response for MongoHQ during the beta release has been (literally) overwhelming. The CommonThread team is planning for 2010 to be a banner year for MongoHQ and with our cloud infrastructure in place, our commitment to expanding our services on the Amazon EC2 platform and with the Engine Yard team behind us, we are confident that our growth will be stable and sure-footed.

Finally, we want to offer special thanks for the help Ezra Zygmuntowicz provided during the transition. As a leader at Engine Yard, he is committed to helping others succeed and has contributed in numerous ways to the open-source community. He has our utmost respect.

Stay tuned for more exciting news from MongoHQ!

The CommonThread Team

About MongoHQ

MongoHQ is a cloud-based hosted database solution that allows you to quickly and easily create and interact with MongoDB instances. MongoDB is a scalable, high-performance, open-source, schema-free, document-oriented database platform that utilizes the simplicity and power of JSON-like data schemes.

Media Contact:
Jason McCay, CommonThread
jason@commonthread.com
(205) 999-5331

About Engine Yard

Engine Yard provides automation technologies and services for Ruby on Rails, including Engine Yard Cloud, an application services platform for web developers and web teams. It provides easy-to-use, automated Rails application deployment and management, with a design philosophy that allows easy migration of existing applications. Engine Yard employs top industry experts and sponsors or contributes to many Open Source projects and efforts such as Ruby on Rails (www.rubyonrails.org), JRuby (www.jruby.org) and Rubinius (www.rubini.us). Headquartered in San Francisco, Calif., Engine Yard is backed by Benchmark Capital, New Enterprise Associates, and Amazon.com. Visit www.engineyard.com.

Shifting our Work Environment

Written By: Jason McCay

June 26th, 2009

Recently, we decided to make a change to our primary office location and moved from our home at Innovation Depot to a new space at Shift Workspace. While we certainly enjoyed our time at Innovation Depot, there were a few specific reasons why we felt that we needed to make this change.

Community

Ultimately, when we formed CommonThread, our goal was to have a company that was visible, active and took part in the local technology community. The open-door policy and transient nature of Shift Workspace allows for that to happen. We can easily invite people to drop by and work with us and more importantly, can work downstairs with some of the most talented freelancers in the Birmingham area. Having our company behind locked doors and security made us less accessible.

Supporting the Dream

We love the idea of co-working and while we admit that the suburban-flight that occurs each day makes Birmingham not one of the more attractive places for co-working to flourish, we had a strong desire to be on the forefront of this new way of working. Other cities (Austin, San Francisco, New York, Philadelphia and Chicago) have had great success with this concept and with areas like Homewood, Bluff Park, Cahaba Heights and Highlands filled with young professionals, the opportunity is certainly there.

So, CommonThread wanted to be in a place where we could help fund this initiative and see it grow in Birmingham.

Connect the Disconnected

As the day goes on, many in the Birmingham technology community are finding a myriad of ways to connect with each other through social media and local user groups, but are rarely connecting in person to work together, share knowledge and expand their expertise. This is disappointing because most of these individuals sit just a couple of miles apart each day. Why not take a couple of days out of a week and work together? There is a completely separate blog post coming on this topic alone.

Different Companies Working Together

The beauty of the Shift Workspace arrangement is that the space for daily use is located downstairs while permanent companies have dedicated space upstairs. Since the upstairs layout is open, a community of small companies is created, allowing for people with different expertise to work together, share knowledge and help grow each other. The result is an environment that promotes new ideas over stagnation and assists small companies that do not contain within them, alone, the differing focuses of larger organizations.

Overall, Shift Workspace feels more like the home that CommonThread hoped for when we first dreamed up our company. Having the opportunity to connect with Drew Jones (who is co-author on a book about co-working in the United States) on this amazing new Birmingham work concept was something that we felt we could not pass up. We desire to see this project succeed and with a bit of effort, we think it will. I plan to write some additional articles covering more in-depth topics referencing our commitment to this way of work in the coming weeks and months.

Come hang with us one day. We would love to talk to you.

Removing Stale Sessions in Heroku

Written By: Ben Wyrosdick

May 11th, 2009

Removing stale session in any app is necessary to keep a clean and happy DB. With Heroku apps it is even more important since you don’t want to pay more for a bloated DB with stale data. Heroku makes it easy to run cron tasks by calling ‘rake cron’ against your app every hour. for more info on Heroku cron support see their docs page.

To setup your cron job on Heroku create the file lib/tasks/cron.rake and place the following code in your file:

task :cron => :environment do
  puts "Removing stale sessions ..." 
  session_count = CGI::Session::ActiveRecordStore::Session.delete_all(['updated_at < ?', 1.hour.ago])
  puts "#{session_count} sessions removed" 
  puts "done." 
end

Loading Session Data in Console

Written By: Ben Wyrosdick

February 10th, 2009

If you need to get data out of the session into an object in console you can use the session object to inspect it. This example assumes you are using ActiveRecord as your session store.

CGI::Session::ActiveRecordStore::Session.find_by_session_id("some_session_id").data

you can find this session_id, for example, in the production.log file on each request.

Textmate Footnotes with vim support

Written By: Ben Wyrosdick

June 11th, 2008

I just switched to doing rails development in vim rather than textmate but I sure did miss my textmate footnotes. I found a post about a plugin called redit that converted stacktraces over to links that would open in vim (textmate footnotes style) so I decided to take that and patch Textmate Footnotes. I had to make sure not to messup any of the developers who were going to still use Textmate so it patches it to do both based on an env variable we will talk about later.

Redit Controller

First I took the controller from the afore mentioned plugin and tweaked it to make sure we were running in development mode before executing code on the server and changed it to use MacVim as the vim app. Simply create a new controller called ReditController and paste the code below changing the system call if you use something other than MacVim.

require 'base64'
class ReditController < ApplicationController
  def open
    if ENV['RAILS_ENV'] == 'development'
      file = Base64.decode64(params[:id])
      line = params[:line].to_s

      # Run editor here
      Thread.new do
        ### MacVim
        # Open file in new tab of vim server
        system("mvim","--remote-tab","+#{line}",file)
      end 
    end
    redirect_to :back
  end
end

Textmate Footnotes Patch

Next you need to replace the lib/textmate_footnotes.rb with this one. I am working with an older version of textmate footnotes so be forewarned that my file may not work 100% with your version … I will update to the latest soon and update my file. Here is an example of how the patch changes the urls generated:

def controller_url
    if ENV['FOOTNOTE_APP'] == 'vim'
      escape(
        "/redit/open/" +
        CGI.escape(Base64.encode64(controller_filename)) +
        (index_of_method ? "&line=#{controller_line_number + 1}&column=3" : "")
      )
    else
      escape(
        textmate_prefix +
        controller_filename +
        (index_of_method ? "&line=#{controller_line_number + 1}&column=3" : "")
      )
    end
  end

Environment Variable

And lastly to make the plugin give you vim links rather than textmate links you need to set the FOOTNOTE_APP env variable. To make this happen every time you login place the following snippet in your ~/.bash_profile

export FOOTNOTE_APP=vim

Twitter Hacking

Written By: Ben Wyrosdick

June 5th, 2008

I got overloaded with work the other night so I decided to take a break from it and hack out something fairly useless but fun. I landed on a twitter bot that updates a few times daily with weather updates for my area or others I might care about. Right now I only have a Birmingham Weather and a Montgomery Weather.

The code requires 2 gems twitter & yahoo-weather. you can install them both with:

sudo gem install yahoo-weather twitter --no-ri --no-rdoc

Then the code was very simple for querying and updating:

#! /usr/bin/env ruby

require 'rubygems'
require 'yahoo-weather'
require 'twitter'

client = YahooWeather::Client.new

cities = [['35212', 'wxbhm'], ['36108', 'wxmgm']]

cities.each do |city|
  response = client.lookup_location(city[0])
  forecast = "Today's weather: #{response.forecasts.first.text}, Hi: #{response.forecasts.first.high}F, Lo: #{response.forecasts.first.low}F (Currently #{response.condition.text}, #{response.condition.temp}F)" 
  Twitter::Base.new(city[1], 'SUPER_SECRET').update(forecast)
end

Then to make it happen automagically, welcome cron:

00 13 * * * /home/deploy/twitter_wx/update_wx.rb
45 21 * * * /home/deploy/twitter_wx/update_wx.rb

It updates at 8:00am & 4:45pm. I had to put the dates in UTC and take into consideration that I am Central Timezone and add 5 hours to the time for now … if someone knows a better way to handle this in cron please let me know.

Phusion Passenger

Written By: Ben Wyrosdick

June 2nd, 2008

We have been testing out mod_rails Phusion Passenger for a few weeks now on our staging server and one production server that hosts our company website and blog. Today we finally got our hands on the Ruby Enterprise Edition early release, so we are now running the full enterprise passenger stack and I must say that I am loving not having to deal with so many deploy issues like configuring monit, nginx & mongrel_cluster configs for every new app and for almost any configuration change, which we find almost unnecessary now since passenger is handling how many app instances to spawn up and it keeps an eye on instances that crash or get hosed for some reason.

We are able to able to really make better use of our VPS slices with the memory reduction we get from running passenger VS nginx+mongrel.

checkout this screencast or head over to the Phusion Passenger website to try it out for yourself.

Slicehost API Saves The Day

Written By: Ben Wyrosdick

May 20th, 2008

Thanks to slicehost for giving me an API for managing my DNS zones and records via ActiveResource becauase it saved me lots of time and tedious work. I needed to update my TTL settings in all my domains and rather than having to edit all 61 entries I simply made a ruby script to do it for me:

require 'rubygems'
require 'activeresource'

API_PASSWORD = "MY_SECRET_PASSWORD" 
DEFAULT_TTL = 86400

class Record < ActiveResource::Base
  self.site = "https://#{API_PASSWORD}@api.slicehost.com/" 
end

records = Record.find(:all)

for record in records
  record.ttl = DEFAULT_TTL
  record.save
end

and while we are at it lets output all of our info:

require 'rubygems'
require 'activeresource'

API_PASSWORD = "MY_SECRET_PASSWORD" 

class Zone < ActiveResource::Base
  self.site = "https://#{API_PASSWORD}@api.slicehost.com/" 
end

class Record < ActiveResource::Base
  self.site = "https://#{API_PASSWORD}@api.slicehost.com/" 
end

zones = Zone.find(:all)
records = Record.find(:all)

for zone in zones
  puts "zone: #{zone.origin}" 

  for record in records.find_all{|record| record.zone_id == zone.id}
    puts "  #{record.record_type}: #{record.name} - #{record.data}" 
  end
end

There, that was easy.

Running and "The Zone"

Written By: Jason McCay

April 26th, 2008

With any team, while your differences bring true creativity and problem-solving, it is good to have things in common as well. For CommonThread, one of the passions that we all share is participation in triathlons. Of course, triathlons take training and preparation, which brings me to an observation I had the other day while on one of my long runs (as I prepare for the Florida Ironman 70.3 in May).

Climbing the Hill

In quite consistent fashion, I have noticed that it takes a solid 2-3 miles of running to get my body in “the zone” for going long distances. Up to that point, it seems like a fight to maintain pace and maintain determination for what I am trying to accomplish. In simple terms, I have to force myself to get to that point without stopping…what I refer to as “climbing the hill”. I have heard others describe it as a wall, but I see it much more as a steady climb that finally arrives at a place of better performance.

The Zone in Development

Similar to running, I think that getting into “the zone” when developing is not some mystical happenstance. I think it requires good planning and a solid effort to maintain focus when there is such a strong desire to occupy yourself with non-important tasks, such as: checking email, twittering, reading blogs, checking the web, etc. While there is time for that, it is those activities that seem quite beneficial when you are making the effort to get to that place of happy, effortless development.

How I Do It

As I noted above, the most important thing is to take the time to lay out something you want to accomplish and place it in a format that you can look upon often. This will always give you an answer to that question of “Hmm…what should I be doing.” Secondly, make a conscientious effort to turn off distractions for a while. Pick out some good music that doesn’t require your attention at the end of each song, close down twitter and email, and begin the process of climbing the hill. It takes effort on your part to get there and your initial desires will be to break out and look at irrelevant information. But, after 5-10 minutes of effort to maintain focus, the zone will begin to establish itself and you will find yourself immersed in what you need to get done.

Final Thoughts

The zone, while it sounds completely cliche´, is really where some of your best work emerges. Superficial work that you complete while stretched thin in a world of constant interruptions, is generally average and will require additional attention in the future. The zone is important…climb the hill…make the effort to get there.

Cherry-Pickin' in Git

Written By: Ben Wyrosdick

April 19th, 2008

if you are trying to update to a specific commit of a git repository and can’t seem to get git pull to allow you pull that specific commit, that is because it doesn’t work that way. so you type git to see what command are available but it only shows you these common commands none of which are useful for this:

usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]

The most commonly used git commands are:
   add        Add file contents to the index
   bisect     Find the change that introduced a bug by binary search
   branch     List, create, or delete branches
   checkout   Checkout and switch to a branch
   clone      Clone a repository into a new directory
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   fetch      Download objects and refs from another repository
   grep       Print lines matching a pattern
   init       Create an empty git repository or reinitialize an existing one
   log        Show commit logs
   merge      Join two or more development histories together
   mv         Move or rename a file, a directory, or a symlink
   pull       Fetch from and merge with another repository or a local branch
   push       Update remote refs along with associated objects
   rebase     Forward-port local commits to the updated upstream head
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index
   show       Show various types of objects
   status     Show the working tree status
   tag        Create, list, delete or verify a tag object signed with GPG

What you need is git cherry-pick which allows you to update to a specific commit.

usage: git-cherry-pick [options] <commit-ish>

    -n, --no-commit       don't automatically commit
    -e, --edit            edit the commit message
    -x                    append commit name when cherry-picking
    -r                    no-op (backward compatibility)
    -m, --mainline <n>    parent number

git cherry-pick will do a fetch and merge to any commit object and then do an auto commit for you. It will automatically use the commit message of that the select commit object. IF you wish to use a different message use the -e option.

Complex Forms ... Just Easier

Written By: Ben Wyrosdick

April 17th, 2008

I love having the ability to easily create/update multiple objects with a single form. There are some nice railscasts by Ryan Bates that describe how to do this in Ruby on Rails. What I needed was a way to make writing the attribute accessor methods easier. I also decided that there just weren’t enough rails plugins out there … so off to kill two birds with one stone.

The Plugin

The plugin is called association-attributes and it can be found on github. The goal was to make the process more semantic and most of all DRY. I decided that since we already had to have a method on the model to handle the association we would pattern after that. So, the two methods available are has_one_attr & has_many_attr.

The Model

So for a practical example of what this looks like in your model we will use a persons contact info. We also have a plugin out there that makes contact info easier since that is such a standard need and there is no reason to rewrite that all the time.

class Person < ActiveRecord::Base
  has_one :address, :as => :addressable, :dependent => :destroy
  has_one_attr :address

  has_many :phone_numbers, :as => :phoneable, :dependent => :destroy
  has_many_attr :phone_numbers
end

What that does is creates the methods address_attributes & phone_number_attributes on Person so that we can use them in our form. These newly created methods handle creating & updating existing entries for addresses and phone numbers.

The View

We use HAML for all of our views so these examples are no exception.

- fields_for("person[phone_numbers_attributes][]", @person.phone_numbers.new) do |phf|
  %label{:for => "number"} Phone Number:
    = phf.hidden_field :id
    = phf.text_field :number
A few things to note from this example are:
  • The fields_for has an extra [] on the first parameter … this is because we have a has_many and that tells the browser to treat that as part of an array so that we can have more than one of that same name and it will get put into the array.
  • We are only doing a new item but you would use the same technique to display existing items by replacing @person.phone_numbers.new with a variable of the actual phone number.
  • We have an id hidden field … this is if we use an existing phone number object it will update rather than creating a new object. (it still works without that but deletes the old number and creates a new one)
- fields_for("person[address_attributes]", @person.build_address) do |af|
  %p
    %label{:for => "line_1"} Street Address:
    = af.text_field :line_1
  %p
    %label{:for => "city"} City:
    = af.text_field :city
  %p
    %label{:for => "state"} State:
    = af.select :state, Address::VALID_STATES.map{|s| [s,s]}.sort
  %p
    %label{:for => "zip"} Zip:
    = af.text_field :zip

In future versions I will have a helper method that writes the fields_for for you as well. Looping through current objects and having an option to put a blank one at the end.

The Result

The result of this is that now when you submit a form to create or update a person that has these subforms using fields_for then the appropriate phone number and address objects will get created or updated as well. No more having to create the person first then associate the extra objects later. Even in the case of a has_many where the object is new it will create the object for you then create all the association objects next.

Jason Presents HAML to Barcamp

Written By: Ben Wyrosdick

April 15th, 2008

At BarCampBirmingham2 Jason made a presentation on HAML & SASS.

You can view the slides here on slideshare.net

Setting Up a Git Server

Written By: Ben Wyrosdick

April 13th, 2008

Setting up a remote git server is as easy as setting up a new user. In fact if you have git installed on the machine that is about all you need to do. We will not discuss setting up git … just how to set it up to be used as a remote repository.

Setup git User

First we need to setup a user with a home folder. We will store all the repositories in this users home folder.

sudo adduser git

Rather than giving out the password to the git user account use ssh keys to login so that you can have multiple developers connect securely and easily.

Create a Repository

Next we will make a repository. For this example we will work with a repository called example. Login as the user git and add the repository.

# login to remote server
ssh git@REMOTE_SERVER

# once logged in
mkdir example.git
cd example.git
git --bare init

That’s all there is to creating a repository. Notice we named our folder with a .git extension.

Also notice the ‘bare’ option. By default the git repository assumes that you’ll be using it as your working directory, so git stores the actual bare repository files in a .git directory alongside all the project files. Since we are setting up a remote server we don’t need copies of the files on the filesystem. Instead, all we need are the deltas and binary objects of the repository. By setting ‘bare’ we tell git not to store the current files of the repository only the diffs. This is optional as you may have need to be able to browse the files on your remote server.

Commit to Remote Repository

Finally all you need to do is add your files to the remote repository. We will assume you don’t have any files yet.

mkdir example
cd example
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@REMOTE_SERVER:example.git
git push origin master

replace REMOTE_SERVER with your server name or IP

Bring It On

Written By: Ben Wyrosdick

February 28th, 2008

It’s fun to dish out criticism but it’s a bitter pill to swallow when it comes back at you. Anthony said that he was most impressed by Dr. Nic’s ability to take criticism for one of his latest projects and use that to improve his product rather than tell everyone they were wrong or just didn’t get it. The truth is that there is always someone out there with a better way to do something, and by listening to your critics you just may stumble upon the solution you were actually looking for all along.

Tip: Rails Default Data Migrations

Written By: Anthony Crumley

February 24th, 2008

Data migrations for default values can be messy. When creating default data, migrations can get lengthy and cluttered with…well…data. Down the road they can cause problems when the model they depend on has been removed.

The clutter issue can be resolved with Fixtures.create_fixtures and a YAML file containing the default data. The deleted model issue can be resolved by defining the model in the migration (Rails Recipes #30).

Example:


require "active_record/fixtures" 

class CreateCategoryData < ActiveRecord::Migration
  class Category < ActiveRecord::Base; end

  def self.up
    Fixtures.create_fixtures(
      "db/fixtures", 
      "categories", 
      :categories => "CreateCategoryData::Category" 
    )
  end

  def self.down
    Category.delete_all
  end
end

Correction: I left off the class_names hash from create_fixtures. This parameter causes Fixtures to use the locally scoped model rather than the global one, e.g. CreateCategoryData::Category rather than Category. (2/25/2008)