Hacker News new | past | comments | ask | show | jobs | submit login
Ruby Patterns from GitHub's Codebase (zachholman.com)
187 points by nephics on Feb 29, 2012 | hide | past | favorite | 32 comments



I was under the impression that the good folks at github were using Vagrant in some capacity. Assuming they've used it or heard of it I'm wondering if/how it fell short for their server based projects.


We're using vagrant to a very limited extent. It's kinda slow (thanks RubyGems!) and overly complicated (why the hell does it use that huge COM-like API thing when it could just shell out to the command line utils?) It's been mostly replaced with two or three short bash scripts now... but they are relatively specific to our app.

In short, the world needs a Vagrant-clone that's < 500 lines of bash.


It's funny you should mention the virtualbox gem. Originally the library did just what you described but the switch back to shelling out was made for windows compat in 0.9

Worth checking out again.


I'm scanning the GitHub repository and it doesn't seem much different from when I last looked. The code is extremely Java-y. I wanted to make a small change to some command (I forget what), but I had to wade through 4+ levels of indirection simply to find a single line of code doing the real work.


My understanding is Vagrant is an important tool used heavily on the GitHub Enterprise side of things. It's distributed as a virtual machine.

- https://enterprise.github.com/faq


I don't know Github's reasons, but I can tell you mine!

Unnecessary statefulness for what should be a script sucks.

Running a whole VM just to run an app is immensely irritating.

Also, Vagrant breaks in the same ways the usual bundler mess breaks as well.


> Running a whole VM just to run an app is immensely irritating.

Although starting a VM to run an app is irritating, spending time hunting down why your build is breaking (or worse, why production is breaking) because someone had a library a few minor versions out of sync or because they're on a different operating system is immensely more irritating.


I'm not sure what your opposition is.

It probably depends on what you're doing, but I've found Vagrant extremely valuable for doing sysadmin work. I do a lot of work with Chef for various clients, and Vagrant makes it trivial to test. From a clean Ubuntu or CentOS VM to a running system in a few minutes. I could see a lot of benefit to using this for application development and testing as well.


This was the original reason that Mitchell and I started the project. We were Rails consultants at the time who just got sick of juggling application environments.


> Unnecessary statefulness for what should be a script

Can you clarify your meaning here? I fail to see how sequestering n random server components inside a vm, or vms, is more statefull than doing the same on your workstation.

[edit] I upvoted your response, because I appreciate your other points


I really miss his videos. Looking at slides without any commentary isn't that interesting.


Regarding the part where you say "document everything". I'm assuming you come from a mid-sized company standpoint where there is more than 1 person working on the app. I might be wrong but I think documenting everything from the start is counterproductive.


Curious as to why you think documenting everything from the start is counterproductive. Are you opposed to documenting everything or documenting from the start, and why?

I mean, I hate writing documentation, but as someone who has had to come back to code I've written months prior (and I was the only one to work on the project), let alone code someone else wrote, I'm incredibly grateful when I look at old code that's actually documented. Plus I feel that writing a couple lines of documentation helps me figure out exactly what I want the code to do.


True. I have been in that situation too. Although I also have some cases wherein I thought prototyping something up to a point to prove it's worth is not subject to "document everything." I guess my question now is, is it better to do it from the very beginning knowing this fact?


Since I think accurate, up-to-date documentation is as important as existent documentation, I'm inclined to believe that documenting everything doesn't have to be started at the beginning, but I know the longer I put it off, the less likely I am to actually write it. I've been trying to document my code as soon as I have a good idea of how the function, method, etc. is going to work, which sometimes is before I write any code, sometimes after I'm finished, but usually as I'm writing it.


GitHub IS a mid-sized company with more than 1 person working on the app.


If all goes well, you'll be a mid-sized company at some point. I say that from painful experience - we're about to hire our second developer at work, and I'm not looking forward to the time it's going to take to document all those little edge cases that I know about, but they won't.


It really depends on what your end goal is. Building a quick prototype doesn't need documentation, but building a long-lasting app that's maintainable and scales well with a growing dev team, documentation is extremely important.


Any examples of library-in-app in the wild. I get the idea, but want to know what this looks like in practice.

Mounting engines or Sinatra apps? Creating a new gem to for extractable functionality? Just curious about what this looks like under the hood.


I don't agree with code is not readable. If the code is not readable, you really need to look at your naming conventions and abstractions.

Using documentation as an alternative to readable code is a pitfall.


Could you give more detail about how you use inner-app services? They seem like a good way to manage project complexity, but I can't find much documentation on how they work in Rails.


Do your Sinatra apps have access to the Rails models?


I don't know what github is doing about their models, but I have fairly easy solution of my own: I always symlink models in my projects.

We have 2 large Rails projects and an API server using Goliath[1], one of the Rails projects and the goliath server use models with symlinks.

[1] Goliath: http://postrank-labs.github.com/goliath/


Why not package them as a gem?


We are still doing massive development, once our codebase is stable enough we will move them into small gems, right now it's just a bit of hassle running bundle update for every small increment.


You can plan this migration ahead of time by moving your models into gems stored in, say, vendor/future_gems/. Then just reference each gem in bundler as:

gem "my_models", path: "vendor/future_gems/my_models/"

Once you are able to break them out completely, just remove the path reference and use a gem server instead.


Yup, they're all mounted in the same ruby process.


Are you able to provide more detail on how something like this would be set up?


Rails 3.0 just does this; given a FooApp Sinatra object, yo can match "/foo" :to => FooApp.


Also doable without rails:

  # In config.ru
  # App, V0, and Resque::Server are each sinatra apps
  run Rack::URLMap.new({
    "/"       => App.new,
    "/v0"     => V0.new,
    "/resque" => Resque::Server.new,
  })


Any app built on Rack (which includes Rails, Sinatra, and many other Ruby frameworks) can be mounted this way. See http://guides.rubyonrails.org/routing.html#routing-to-rack-a...


We use Unicorn, which provides a Rack handler for Rails 2.2 apps. I just mounted the an API router app before the Rails handler in our config.ru. The API router app is just a big regex that looks for API related urls, or passes through to Rails. Though, jnunemaker recently showed me a trick where you can mount Sinatra apps in other Sinatra apps through `#use` (like any Middleware). I may try that out and get away from my ghetto regex routes.

We recently upgraded to Rails 2.3 which is built on Rack. `ActionController::Dispatcher.new` is the last Rack app on the stack now.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: