My new love: Codebase-HQ

I have discovered a great new project management service called Codebasehq.com, which merges Github and Lighthouse with a pleasant and seamless integration.  It answers a lot of my wishes for the features that are needed when dealing with a “whole-project” lifecycle.  I’ll talk about the basic features and subareas of the site, but first I want to highlight what truly makes Codebase a game-changer:

Project management

When you create a project in Codebase, you are given access to a number of critical features that disjointed services like Github and Lighthouse just can’t offer.  To start with, the unified user management is terrific.  If needed, you can get into some very decent ACLs to custom each user’s interaction.  If that’s not important to you, then the standard user setup is fine and the ACLs won’t get in your way.  Each project can also have several repositories, which is great for for when you have separate repos for Rails, design files, data files, etc.  Having your wiki, repos, tickets, and more aggregated into a single unified structure is awesome and really transforms how everyone understands the state of a project.

The individual featuresets that go into creating such great project management are:

Git hosting

Git hosting on Codebase is nearly identical to Github.  And that’s a very good thing.  Repo browsing, navigation, etc is pretty much the same (if not better) and you get the important extras like deploy keys and whatnot.  You can also set a repo to constantly sync/mirror another.  It is missing some of the more flashy Github features, like the forking integration and network/commit graphs, but overall is quite polished and very capable.

Ticketing

Ticketing is similar to Lighthouse in its simplicity.  In some areas its a little less feature rich:  email integration is not so great right now (should get better) and you can’t customize your statuses for tickets.  In other areas it’s vastly superior, especially in the general gestalt of the interface which is much easier to use and navigate.  It is still missing the one feature that I wish all ticketing systems had: a public support interface where non-users can submit and track tickets.  But since no one else offers it either, I can’t complain much. (Tender is getting close, but they’re taking their sweet time and so far I’m not a fan).

Milestones

Pretty much the same as any other milestone system.  It has one KILLER feature though: milestone/branch integration.  If you start off a git branch for your milestone, you can tie them together so you can track commits specific to that milestone. It’s incredible and stands as a great example to what can be done with true integration.

Wiki

Github offers a wiki, but it’s a pain to edit and I generally don’t bother with it.  Especially because for an ‘enterprise’ project, many of the people who need to read the project’s wiki don’t even have github access (or even know what github is).  Codebase’s wiki is more traditional in its setup and works great.

Time tracking

A very nice addition that is important on many many projects.  You might not always need it, but if you do, you’ll love it.  It is simple, straightforward, and works well.  I’d like to see it integrate even more closely with tickets, but otherwise a small to medium sized team will have little to complain about.

Summary

Although both are very similar and center around git repositories, Codebase and Github do not fill the same role.  For your open-source projects, Ruby gems, and such: stick with Github.  The forking/networking features and wide community acceptance make for an unbeatable setup.  But when it’s time to get a whole dev team together on a project, Codebase definitely has the upper hand.  They have a great set of features (and are coming out with more all the time) and the overall integration and polish makes it a joy to work with.  Their pricing is also incredibly good (even if it is in Euros), so please check them out.

Comments (1)

Big changes in Rails coming

I prefer posting brand new content and usually avoid “re-propagating” news, even in the Rails space. However, the major happenings of the last two weeks in the Rails community have prompted me to speak up. It all started with some rather unpleasant video exchanges between Rails-ists and Merb-ists about their differing theories in framework development. Out of that came a big discussion about where Rails and Merb were headed and before anyone knew it, The Merge was announced.

At first I was amazed.  I’ve always loved having both Rails AND Merb.  I felt that having two different philosophies side-by-side allowed the community to try out new ideas in a very small and agile way (in Merb), and the ones that were really good surely found their way to Rails shortly after.  Let’s face it, Rails is growing up fast and doesn’t have the luxury of breaking backward compatibility like it used to and it’s no longer able to explore the “what-ifs” like before.  But we still had that ability in Merb.  So at first I was a bit concerned.  But I still think this is a great new direction to take.  And even with the reduced flexibility, I’m really excited to have all this awesome brainpower concentrated in one place.  I can’t wait to see (and use) the end result.

Today an addendum was added to this new revolution.  It’s been announced that there will be a Rails Activist group.  The Rails Activists will champion Rails (and of course Merb) across the universe.  They will act as a voice for the community both to the Rails Core team and to the world-at-large.  There’s a UserVoice site, a Google group, and more for helping the community express their opinions.  This is a truly awesome idea and I’m even more excited to see what these guys can do for Rails.

Comments (1)

Odd Rubyism

Today I found a little counterintuitive oddity in Ruby.  Take the following code example:

a = [0,1,2,3,4,5,6,7,8,9,10]

h = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5,
     6=>6, 7=>7, 8=>8, 9=>9, 10=>10}

puts "Iterating & deleting array"
a.each do |i|

  puts "On #{i}"
  if i % 3 == 0

    puts "Deleting #{i}"
    a.delete(i)
  end

end

puts "Iterating & deleting hash"
h.each do |k,v|

  puts "On #{v}"
  if v % 3 == 0

    puts "Deleting #{v}"
    h.delete(k)
  end

end

With the output:

Iterating & deleting array
On 0
Deleting 0
On 2
On 3
Deleting 3
On 5
On 6
Deleting 6
On 8
On 9
Deleting 9
Iterating & deleting hash
On 5
On 0
Deleting 0
On 6
Deleting 6
On 1
On 7
On 2
On 8
On 3
Deleting 3
On 9
Deleting 9
On 4
On 10

Notice how each time the array deletes an item, it happens to skip and never evaluate the next item? Ruby internally uses an index counter (like if you were manually iterating the array with a for loop). When an item is deleted everything shifts back one.

With the Hash (it’s a little hard to see because they’re out of order) no items get skipped.

I’m not saying this is a bug or is necessarily wrong, but a Hash and an Array are very similar data structures (especially insofar as they are both enumerable) and I’m surprised that they work differently. I also spent a LONG time and a LOT of debugging to figure out that this was the error (it was buried deep in some XHR Rails calls, so reproducing it took a lot of time)

I’d love to hear from anyone who can attest to what happens in other language iterators (Java, Python, etc)!

Comments (3)

Presenting gem_cloner

Besides being a Ruby/Rails/Merb developer, I’m also a part-time sysadmin for a number of previous clients.  Usually I’m responsible for maintaining Rails stacks, either for apps that I’ve written or just for another developer that doesn’t have as much Linux experience.

Lately, I’ve had to do a move of a number of Rails installations to completely new/clean servers.  I’ve got lots of scripts for doing initial setups of the stack as they need to be.  But one thing that comes up is that, especially with older apps, the gem dependencies can be very finicky.  Installing the latest versions will almost certainly break something.  Plus some times the system can have quite an extensive list.

Yes, I know that the gems should be packaged with the app, but there are a lot of reasons that it doesn’t always happen or doesn’t always work.  To that end, I’ve found the most effective method is just to re-install the exact same set of gems on the new box as the old one.  To automate this process, I present: gem_cloner.

gem_cloner is a very tiny but useful script that will take the text output of `gem list`from one machine and execute the `gem install` command on the new machine.  Usage is very simple:

  1. On the old machine, run `gem list > gems.txt`
  2. Copy gems.txt to the new machine.
  3. Copy the gem_cloner.rb file to the same place
  4. With sudo or as root, run `ruby gem_cloner.rb`

The script will read that file and install the exact same gem versions.  You’ll definitely want to browse and tweak the script.  Possibly by adding ‘sudo‘ in the command call or adding ‘–no-rdoc –no-ri‘ (I personally use a gemrc to eliminate the doc files on production systems).

Fork, patch, & praise ad nauseum on github and drop me a line if you like it.

Leave a Comment

RubyConf Summary Day 2

Ah, another day of RubyConf has passed.  Here’s a brief overview of the talks I attended and my thoughts on them.  The theme for today was definitely Threading and Concurrency.  And the conclusion in many (if not all) of the cases was:  Ruby sucks at it, how can we make it better?  I hope that Matz, et al takes these issues to heart and prioritizes some improvements in this area.  Native threads are a start, but the GIL kills us.  We need more!

Aristotle and the Art of Software Development – Jonathan Dahl

What a way to start the morning!  Jonathan gave an overview of several great philosophers and how to apply their ideals to programming.  He likened Perl, Java, and PHP to the school of Utilitarianism, where the ends justify the (very) nasty means of getting there.  His basic theme throughout the presentation was that hard rules (from any school of thought) must be tempered with common sense.  He gave the example of DRY versus clean & understandable code in ‘database.yml’.  While the clean version has a lot of redundancy in the settings, DRYing it makes it impossible to read.  Overall, a great way to start the morning.

Ruby Arduino Development – Greg Borenstein

I caught a Ruby electronics talk last year that was pretty cool, and got an even better one this year!  Greg presented a number of cool arduino projects, including drumming with servos, a temperature reader using a big red arrow on a servo, and a drink mixer that could make screwdrivers using windshield washer pumps!  It was a terrific overview of RAD and I can’t wait to buy an Arduino when I get home.

Better Ruby through Functional Programming – Dean Wampler

Dean did a nice talk about using functional paradigms in Ruby.  He gave examples of makign sure your functions don’t modify state, pattern matching, using functions as first class objects, etc.  He gave a good comparison that showed that DSLs are very similar to functional languages because they are very declarative instead of imperative.  What I think he missed is that, under the hood, DSLs are very state-heavy in order to implement that declarative model.  It was great to delve into these ideas, but I was left feeling that if you go through the trouble of following functional programming in Ruby, you don’t really get any benefits.  Ruby isn’t optimized for concurrency like Erlang or Haskel and your code will really just be more difficult to trace.  Maybe I’m missing something, but I didn’t see the benefits (except making it easier to switch to a functional language).

What Every Rubyist Should Known About Threads – Jim Weirich

When I see Jim’s name on a talk, it is guaranteed I will attend.  I don’t care about the subject.  Jim is an amazing speaker with always interesting topics.  He gave a fairly basic overview of concurrency and why we need it (the failure of Moore’s law).  For Java programmers and the ilk, this would be concurrency 101, but probably had some new information for a lot of Ruby developers.  He provided some great code-heavy examples of race conditions and deadlock and how to work around them.  He also hammered home his message of ‘Concurrency is HARD’, but it must be done.  However, I felt there was a kind of elephant in the room with the fact that concurrency in Ruby is rather fruitless, thanks to green threads, GIL, etc.  Jim did, however, give some great examples of ways to make it easier:  Erlang & Clojure.

Using Metrics to Take a Hard Look at Your Code – Jake Scruggs

Jake gave a terrific presentation on how use metrics appropriately to help improve and maintain your code.  He talked about code coverage, testing, Flog, Saikuro, and more.  Jake also had a great example of applying these tools to target improvements with a real-life example of refactoring a Dameau-Levenshtein distance function.  He also had great example of how inject has a tendency to muddy your code significantly, increase complexity, and decrease understandability, a sentiment I whole heartedly agree with.  Best of all, Jake introduced Metric-Fu: http://github.com/jscruggs/metric_fu .  Metric-Fu combines, code coverage, flog, saikuro, and more into an easy to use interface that integrates with CC.rb.  Looks awesome and I’ll be trying it out soon!

Components are not a Dirty Word – Mike Pence & Nick Sutterer

One of the few Rails talks at the conference (as it should be).  Mike introduced us briefly to ‘Cells’, a new type of Component more similar to what Merb has now.  The Nick came up to demo Apotomo, a plugin that provides wholey-contained stateful widgets.  These widgets are persistant and handle updating their own appearance.  They also have event triggers, observers, and caching.  I will definitely be giving Apotomo a try, at least to play with, although it may not be ready for production use yet.

Ruby Kata and Sparring – Micah Martin

Micah talked about his experiences with martial arts and how it can be applied to programming.  His message was “To be a master, you must use disciplined practice outside of work”.  This is the purpose of Kata, or Forms.  He gave many reasons for a similar approach in development: peer feedback, definite goals, performance, etc.  He even performed a Kata of developing Langton’s Ant right on stage.  The best part was his introduction of a new tournament: battleship.  All Ruby developers are invited to participate by building a battleship AI.  The tourney info is available at: http://sparring.rubyforge.org/battleship/ .   Awesome indeed, you can be sure I’ll participate.

Ruby Heavy-Lifting: Lazy load it, Event it, Defer it, and then Optimize it – Ilya Grigorik

Ilya gave a great talk on how to break down a task into something where you can use multiple processes.  This is the good stuff.  Forget threads and concurrency problems.  If you truly isolate the tasks (share-nothing? hello?), you begin to produce a system that can massively scale very easily.  He demonstrated using his real-world example of scaling AideRSS.com.  They split off the different tasks: network-bound, IO-bound, CPU-bound.  The different processes communicate with message and job queues (he mentioned starling, beanstalked, and SQS) and they used EventMachine to prevent blocking-IO.  In the end, they could load each EC2 instance with basically one task of each: saturating network, IO, and CPU simultaneously to get the best bang for the dollar.  Overall, the talk was great, but I may be biased since I feel it basically validated all my experience and convictions about the RIGHT way to scale.

Keynote – Dave Thomas

To round out the evening was Dave with a literally breathtaking talk.  He gave an example of Ruby’s biggest problem (at least I think so): slow development.  Ruby had 48 months between 1.6 and 1.8 and it’s already been 52 months waiting for 1.9.  (I guess Matz has really taken to heart his goal of being ‘enterprisey’)  This causes INCREDIBLE problems for migrating to a new version, not to mention learning or using the new features.  It also leads to slower adoption, wheich means less usage of the new version, which makes even LONGER releases.  Dave’s solution is to Fork Ruby.  He proposed four forks, all VERY good ideas.

RubyLite – A version of Ruby where we strip out a lot of the unnessessary stuff.  Dave projects Ruby’s codebase to be 100MB when 2.0 is finally release (in 2011!).  Pulling out a ton of unneeded syntax, libraries, and redundant methods could significantly improve size and performance.  I’m all in!!

Parallel Ruby – Dave proposes a ruby that will automatically parallelize certain operations.  A new operator: //= would perform something similiar to:  a,b=b,a using passed procs simultaneously.  Basically distributed map automatically.  Awesome idea.  Have no clue where to begin with this one though.

Typed Ruby – Ruby with typing.  Charles Nutter has been workign on something very very similar to this with Duby.  Cool idea, but I love duck-typing too much.

Closure-based Ruby – Dave offers a new syntax for hashes that will free up braces (not a bad idea, if there’s an =>, you already know it’s a hash, the braces aren’t really needed, just like with implicit arrays right now).  The braces can be used to element all the Lambda, proc, Proc.new, block madness.  Make ONE first-class proc object, that can be passed and used all over the place.  A GREAT idea!!!  I think he took it a little far when he suggests making class and method definitions using it.  The code at the very end looked like Lisp with braces all over the place, you couldn’t tell what was what.  But otherwise, I whole-heartedly support a simplified proc system in Ruby.

Dave closed by saying that he hopes that he inspired us to go out and impliment these ideas, or any others we may come up with.  Try out new things and maybe they’ll get merged into MRI.  I sure hope RubyLite and the closure system Dave proposed eventually get taken into MRI.  I may even take a crack at implementing them myself!

Comments (3)

RubyConf Day 1

During RailsConf this spring, I provided thrice daily (or more) posts on the talks and events.  While they were very popular, I didn’t really get to enjoy the conference much.  This time, I’m limiting myself to shorter notes once per day.  Here is a brief recap of Thursday, Day 1 at RubyConf.

The theme for RubyConfat RubyConf so far is DSLs.  While DSLs are always a promenant topic, so far every talk has included a pretty extensive coverage of them (or how they are used in a project).  This isn’t at all a bad thing, as I believe DSLs are very powerful, produce clean code, and are of great benefit to Rubyists.  That said, I don’t get to write many of them, so I’m a bit rusty and looking forward to beefing up my skills at Neal Ford’s ‘Advanced DSLs’ tomorrow.

Matz’s Keynote
Matz was his usual comedic self.  The talk was quite good and very sentimental.  As he notes, he doesn’t like a lot of technical content in his keynote.  Instead, this was more about how great the community is and he provided a lot of encouragement to keep that up, no matter how much we grow.  He asked for raised hands on “Who started with Ruby because of Rails”.  I’d say about 30% of the room raised their hands.  Then he asked about “Who stuck around because of Ruby” and it was clear that Ruby is why everyone stays.
A oft repeated quote from the keynote:  “Rubinius, yea – Good try”

Scaling Ruby (Without Rails) by Gregg Pollack
Gregg (of RailsEnvy) did a nice talk about what you should keep an eye on when developing in Ruby and trying to maintain decent speed.  He noted that Design Patterns in Ruby has many great examples, but they are necessarily slow.  Matter of fact, in general, making method calls are much slower than the alternatives.  I think this was great to hear as it reinforces my coding style of avoiding things like ‘.nil?’ or ‘.zero?’ that are expounded by other Rubyists.  I believe the more traditional routes are just as understandable without being so expensive.

Gregg also talked about threading (also a popular topic at RubyConf this year), Neverblock, Mongrel vs. Evented Mongrel, Deferred requests, Rind, DBSlayer, Halcyon, and Ruby-prof.  Overall, not bad, but a little light on content, examples and details.

Using Git in Ruby Applications – Scott Chacon
Scott gave a nice talk that included a brief overview of git itself followed by explaining some unusual things that git could be used for, including a ticketing system, wiki backend, and more.  His major goal was to introduce Grit, a Ruby library that allows you to interact with a git repo through Ruby.  It was pretty neat, but also quite complicated, even for git veterans.  There were quite a few code examples, but I didn’t really see any ’start-to-finish here is how you do this’, and I think it was just a bit too much for the talk.  Overall though, it looks like a nice library and I hope to try it out more later (possibly for some interesting Rails/Capistrano tasks)

Recovering from Enterprise – Jamis Buck
I actually debated whether to attend this talk or go to another because it looked to be a bit beginner.  Boy, am I glad I stayed.  Jamis gave a terrific talk about his experiences writing and re-writing dependency injection libraries Copland & Needle.  After a nice, fairly technical walkthrough, we get to the meat of the conclusion:  Ruby-style dependency injection doesn’t require a dependency injection library at all:  Pass the class name or overwrite a helper method and go!  He left us all with some great quotes and nuggets of knowledge:

“I was riding the Dependency Injection horse for all it was worth”
“If you were turning every ten lines into a component, then you just wind up with component soup.  And I hope you’re hungry”
“Just in time.  Not just-in-case”

Unfactoring From Patterns: Job Security Through Code Obscurity – Rein Henrichs

Rein gave a pretty funny talk that went through the procedure for turning good code into bad.  It was funny with a lot of audience suggestions.  I attended hoping for some ‘glimmer of divine knowledge’ from the advertised ‘1% of truth’ to be presented, but there was none.  It was just a good time laughing at poor coding practices.

Peer Aware Desktop Application Development – Preston Lee
Preston presented on a library called ‘Journeta’ that provides a server-less broadcast-based peer-to-peer discovery and communication platform for clients on a LAN.  It’s a pretty fun and interesting topic, although I can’t think of any application of it right now.  Once again, the subject of the inadequecy of Ruby’s green threads came to the forefront.  It provides a severe bottleneck for the kind of asynchronous communication that Journeta does.  As we know (and was pointed out by Gregg earlier), the Global Interpreter Lock in Ruby 1.9 means that we still don’t have an appropriate solution.  I pray that a real solution comes to light soon because Ruby is severely suffering because of it.

Preston noted that Journeta didn’t work for Windows (mostly because he hadn’t tried).  I took that as a bit of a challenge and hacked on it during his talk.  After delving into some interesting internals of the Windows UDP Socket handling, Multicast, etc, I managed to get Journeta working on my Windows machine.  A fun chellenge for sure.  This is definitely what RubyConf is about.

Testing Herasies – Francis Hwang
Another talk I was considering missing, but I’m glad I didn’t.  I would say Francis gave probably the best talk of day.  It was chock full of technical content, examples, and a rather controversial topic: the right way to test.  Francis started with an overview of Mocks, Stubs, Dummies, Fakes, etc.  Then he started in with a great list of testing ‘dogma’ that people are told is the ‘One-Right-Way’.  He provided some excellent examples for why these bits of dogma aren’t necessarily true.  For example, he argued very effectively against Mocks (and the general ideal of seperating your testing from side-effects of external applications).  I hope he posts his slides for later reference, and if I find them, I will be sure to add a link here.

To end out the day, I attended the evening’s lightning talks.  There were a lot, but I’ll note a few:

Ryan Davis (ZenSpider) - Provided an overview of his new gem: Flay.  It’s a tool to find duplicate code, even if the code uses different variable names.
Yossef Mendel – Talked about what is and is not true (Truthiness) in Ruby.  A good reminder that only ‘false’ and ‘nil’ are evaluate to false in Ruby.  Everything else is true.  Yossef provides a funny little tool to see the truthiness of something (but hopefully after his talk, you don’t need it): http://github.com/ymendel/truthy
Bruce Williams was quite popular at RubyConf today as he was selected on Monday by the Obama campaign to attend the acceptance speak in IL as ‘Front Row to History’.  Bruce built a neat site prior to leaving (in one day) that provided updates on his tweets and snaptweets: http://obamaftw.org/ Way to go Bruce, I’m jealous!

Comments (1)

Bad Ruby/Rails interviews

A few of my colleagues from a previous project were recently laid off.

I won’t go into the absurdity of the fact that their company was bought out and the new owners decided they didn’t like the project the developers were working on and showed them the door the very next day with no severance (seriously, who ever negotiated a buyout where the employees are left completely unprotected from the new owners?!).

What I’d like to talk about is what makes a good interview.  One of the guys recently went to an interview for a Rails job with a big-name magazine.  Here is the account of what happened (as told to me).

First, no Rails specific questions were asked, they were all Ruby questions.  That’s a little off-putting, but not a big surprise considering the unique boat that Rails is in.  The nature of the questions, however, were equally confusing.  Here’s an example:

Make a method that reverses a string…without using reverse

Okay, I’d say that this is a relatively easy question, and is probably something that a prospective candidate should know.  But this question still has some major problems when being used to gauge a developer.  Here are my issues with it:

  1. Arrays, Enumerables, and Strings have huge numbers of helper methods.  I would want any Ruby developer to instantly to be able to tell me uses for map, inject, etc, but each_char is not high on the list.  I can’t even recall the last time I used each_char.  Should an interview really hinge on such a random request?
  2. There is no good way to write a replacement for reverse, so why are you asking someone to do so? This question was obviously asked by someone with a C/Java background and formal CS training (don’t yell at me yet…I’m a former C programmer with formal CS training too!).  The point is that this question clearly shows a mindset that doesn’t truly apply to Ruby.  If this were C, there would be an in-depth discussion here about manipulating the char array and the most efficient way to do so.  In Ruby, you don’t really have a choice without access to the underlying representation of the string.  You have to iterate through the object and then stuff it into a new string.
  3. Ruby 1.8 has weird string handling.  If I couldn’t immediately remember each_char, my next approach would be to just iterate backwards with a more normal C style loop.  However, as we know, doing some_string[i] returns an integer, not a single char string.  Great.  Now I have to remember how to convert that int back into a string (ah yes! chr!)
  4. Ruby 1.9 changes the whole game.  String iterators are changing.  As I recall from Matz’s keynote last year at RubyConf, there are so many ways to iterate through a string (char, word, line, etc) that a new paradigm is needed.  How much do you want to bet the interviewer didn’t even know that things were changing?
  5. This question doesn’t tell you anything about the person’s knowledge of Ruby.  Get into some procs, send, mixins, alias chains, or some meta programming if you actually want to test for an understanding of the language.

Unfortunately, our story doesn’t have a pleasant ending.  Not only were his chances at the job ruined because of this one question, it turns out that this is the process for all applicants.  They are progressively given a series of questions throughout the interview process.   Each question has exactly one right answer (yea right!) and the applicant must get every one right in order to be offered the position.  They stopped the interview right there and showed him the door, no chance for any other questions.  I think they’ll be looking for quite awhile.

Leave a Comment

Rails exception monitoring

There has been an explosion of late on new ways to deal with tracking exceptions thrown in a production Rails app.  It used to be that you put in exception_notifier and went about your business.  But not too long ago I decided that I needed more.  Two things started this push:

  1. There was more than just me working on a project.  Several people needed easy access to the exceptions (at times) but I didn’t want to clutter their inboxes with e-mails for every exception.
  2. I would not be working on the project forever and others would be handling long term maintenance.  This meant changing the e-mail addresses in the config file quite often and just felt like ‘the wrong way’ to be doing it.

So I started looking for other alternatives.  Here’s an overview of the three I found:

Exception Logger

Let’s start with the positive.  Exception logger is exactly what I was looking for.  It provides the functionality I was looking for and makes tracking exceptions with multiple users easy.  Unfortunately, the install procedure is a mess.  The standard plugin just would not work for me.  Rails is notoriously bad at handling controllers/models/views that are inside a plugin so exception logger really needs to be built on Engines for that kind of functionality.  Instead, it uses a number of hacks to try and get Rails to recognize the code in the plugin and it just doesn’t work well.  Plus, in order to get added functionality (such as authentication) into the controller, you’re supposed to use a config file!  It’s a crazy unclean mess.  So in order to get it operating, I was forced to simply take the controller, views, etc and put them into the normal app tree.  This took a lot of setup and debugging, but I was able to get it to running and now it works extremely well.  I have it in one high-use production app and I’m very happy but I don’t expect to use it much more.  You lose the ability to e-mail notifications (at least not without hacking some more of the plugin) as well, so it’s only good in a few select cases.

Exceptional

Now we start getting to the fun stuff.  Several new exception monitoring applications have sprung up recently and I decided to check them out.  Exceptional is a hosted service and although I’d really prefer to have my exceptions tracked locally on a per-app basis, having them aggregated does have its benefits.  It’s totally free, so sign up for a username, then create a new app profile to get an api key.  Install their plugin and paste in the key and you’re set.  It runs in production mode and sends the exceptions off to their logging service.  It integrates with lighthouse, campfire, and twitter (none of which I use, but I’m sure it helps others) and will also e-mail you the notifications.

Once again, though, some issues made it unusable.  It appeared to work great, but as I started doing some system administration, I started running into a number of problems.  Whenever the plugin loads (when in production mode) it dumps a set of debug messages to stdout.  Every time time I’d load a production console (for working on a few issues that could only be tested on the production/staging server) I’d get messages about its attempt to connect.  Then a few seconds later, interrupting whatever I started, there would be more messages about the successful connection.  Unfortunately it does this when running rake tasks as well, so all my cron jobs that use rake tasks were now littered with these messages.  I was prepared to just edit the plugin to stop these messages, but instead I came across our next entry.

Hoptoad

Hoptoad is very simple, free, and nearly identical to Exceptional.  Sign up (you get your own subdomain), add an app profile, install the plugin, and copy the api key.  It doesn’t have the extra integrations of exceptional (though I’ll bet they’re coming), but it does everything I need and without the annoying messages.  It also lets you give extra users access to errors from certain apps only (as does Exceptional, although it wasn’t immediately obvious whereas Exceptional appears to be one username only).  One thing I will really miss from Exceptional is that it tracked 404 errors as well.  Although 404s usually come from scan bots, some may very well be legitimate broken links on or to your site, so it’s nice to track them.

Summary

Overall, I would highly recommend Exceptional and Hoptoad for everyone for all their exception tracking from now on.  Which one you use just comes down to a matter of taste right now and maybe your specific requirements.  I’m very excited to see what further features they add to differentiate themselves and I am REALLY hoping to see integration with scoutapp somehow, as I think exception handling and performance monitoring go hand-in-hand.

Finally, please feel free to comment on your own experiences with any of these projects!

Comments (3)

Setting up Git and Github on Windows

Recently I’ve needed to set up a number of Windows XP machines with Git and github access.  It turns out this is not an easy problem, certainly not as easy as SVN.  Most of the problem stems from the fact that all transfers/pulls/pushes to github are done through SSH.  So we have two different apps (Git & Putty) trying to work together and it’s just not as clean as on a *nix based system.  But once things are set up, it works very well.  The first time I did it for myself, it was a wild adventure of trying changes to the PATH, environment variables, keys, etc.  Thankfully, I have it down to a quick and fairly painless science, which I present here for anyone else needing help.

  1. You probably already have a github account. If you don’t, sign-up at least for the free account now.
  2. Obtain the necessary software.  Note that we’re using a pseudo-unofficial version that does not require cygwin.  It works great and supposedly will be merged with the official version soon.
    1. MSYS Git – Used here specifically is preview20080413
    2. Putty 0.6.0 – Download the Windows Installer
  3. Install both packages of software.  They are very simple installs and all the defaults work fine.
  4. Generate your key. This is your personal key that will allow you access to github (and you’ll probably want to use it for accessing servers as well. Much better than passwords). If you already have a private key you’d like to use, then open PuttyGen, click the ‘Load‘ button in the middle, and skip to substep #6.
    1. Open PuttyGen, click ‘Generate‘, and follow the instructions to generate randomness
    2. Add some info to the key comment. I like to put my name in addition to the default
    3. Highly Recommended: Add a key passphrase
    4. Click ‘Save Public Key‘. I named my main key ‘key.pub’
    5. Click ‘Save Private Key‘. I named mine ‘key.ppk’ Save this in a SAFE place. If someone gets this file, they have your identity, just like a password!
    6. Right-click on the box at the top labeled Public key for pasting into OpenSSH… and click ‘Select All‘. Then right-click again and select ‘Copy
    7. On the gihub.com site, click ‘account‘ in the upper-righthand corner and paste the public key into the SSH Public Keys box and click ‘Update Keys‘ (is it all making sense so far?)
  5. First tricky step – Setting up your environment variable. This is what allows Git to find your private key and use it to connect to github.
    1. In Windows (XP) Press WindowsKey + Pause/Break or double-click System in the Control Panel
    2. Under the Advanced tab click Environment Variables
    3. Under user variables (the top set) click New. Set the name to GIT_SSH and the value to C:\Program Files\Putty\plink.exe
    4. Click Ok a few times and close out of that junk
  6. Second tricky step – Accepting github’s identity. Whenever you first connect to a server via SSH, you must confirm that the server you are attempting to connect to is the right one. The server will provide a hash string that (in theory) should be validated some other way. In reality, this is just the ‘leap-of-faith’ step. Here’s a great read for more info on this security step.
  1. Open putty
  2. In the Hostname box, type github.com and click Open
  3. You’ll receive a prompt The server’s host key is not cached in the registry. Click Yes then close Putty (don’t bother trying to log in
  4. Github’s host key will now be cached
  • Launch Pageant – This step must be repeated any time you restart your computer. Pageant must be running anytime you want to connect to github! It’s advisable to close it when you’re not using it, as any other program on your computer could use your private key for any purpose while Pageant is running.
    1. Run Pageant (in the Putty directory on the start menu)
    2. In your system tray you now have an icon of a computer with a black top-hat. Double-click it
    3. Click Add Key, find your private key that you saved above and open it. If you password protected it, you’ll enter the password here
    4. Click Ok. Pageant will remain in the system tray ready to provide your private key to Git

    You’re now all set up to use Git! You may interact, upload, download, etc with any private github repositories that you have access to. As long as Pageant is running, you should have no problem with Git BASH or Git GUI. If you ever receive a message that ‘The remote end hung up unexpectedly‘ it means Pageant isn’t running. In theory, Plink/Putty is supposed to prompt you for the key/passphrase if Pageant isn’t there (at least that’s how it works when tunneling SVN), but this doesn’t happen for some reason. If anybody knows the fix, please let me know!

  • Comments (1)

    Presenting Overloadr: The Great Rails Host Shootout

    or: How I learned to stop worrying and love scaling Rails.

    There has been an explosion in Rails hosting providers: Boxcar, Mosso, MorphLabs, EC2, Heroku, etc. To make matters even more difficult for the typical Rails developer, many of these new providers have very unique properties: scaling/clustering/cloud computing/and more. It’s no longer as simple as Shared/VPS/Dedicated.

    Therefore, I have started a new pet project: Overloadr. The goal of Overloadr is to test two things:

    1. The ease of deploying a basic Rails app to a hosting provider
    2. The relative performance of ’specialized’ hosting platforms.

    To start this off, I’ve written a Rails app that can be used with ab (Apache Benchmark) to test the performance of the Rails engine and the database behind it. The project is available on GitHub, as is fashionable… Feel free to fork, contribute, etc. Eventually I may set up bug tracking, discussion groups, etc. but for now, this is what I’ve got:

    http://github.com/isotopetech/overloadr

    My list of prospective hosts so far is:

    VPS

    • Boxcar
    • Slicehost
    • RailsMachine

    Cloud

    • MediaTemple
    • MorphLabs
    • Mosso
    • Heroku

    Shared

    • Phusion Mod_rails (Dreamhost?)

    EC2 (Testing ease of deployment with different gems)

    • PoolParty
    • ec2onrails
    • rubyworks-ec2
    • Rubber

    A Dedicated server

    You can expect the first of the posts of the deployment experience and performance shortly.

    Comments (4)

    Older Posts »