April 27, 2011

Setting up Passenger Standalone, RVM and launchd on OS X

Filed under: General Information,ResearchAndDevelopment — Ryan Wilcox @ 9:22 am

Installing Radiant with Passenger (Standalone), RVM and Launchd on OS X

Introduction – why Passenger Standalone

I like to deploy all my basic sites on the same host. For example, deploying a Radiant site along with a few small Rails sites on the same box. This keeps things easy for me, and no sense devoting a lot of resource if I know the site will be fairly small.

However, this poses some deployment challenges.

I want to use Passenger, like all the cool kids are doing. Just set up some Apache things and I’m ready to go.

I also always use RVM. It is so amazing being able to keep project gems separate from each other. This is especially important when you have multiple projects on the same machine.

This sounds like a dream team: use Apache/Passenger to host multiple Rails apps, with separate gemsets, end of story.

Except, the real world doesn’t work like that.

First, your rvm and Passenger must share a common Ruby. If they can’t, you must use Apache Reverse Proxy cleverness with other servers (like Passenger Standalone).

The easy way to avoid this mess is to make sure they match. We’re all using REE anyway, amiright?

Actually, usually not. If you’re on a shared host, or host multiple Ruby sites from one box, you don’t want to make everyone on that site use REE… even if it’s the best.

For example, what happens in a year when you’re working on a Rails 3 site in Ruby 1.9… you just forced yourself into yesterday’s version.

It is tempting to set up Passenger to use one Ruby (REE) and point Passenger to your gemsets. I really suggest you go to the extra work and set up this system instead

Setting up Apache as a Proxy

So, we want to use Apache as a front-end, and use reverse proxies to run all these sites on their own Passenger standalone servers.

In your Apache configuration (in /etc/apache2/sites, in a file that increments the leading count):


<VirtualHost: *:80>
  ServerName cms.example.com:80

  ProxyPass / localhost:3000/
  ProxyPassReverse / localhost:3000/
</VirtualHost: *:80>

Note: that trailing slash is important

If you have your Rails/Radiant site on the server, at this point you should be able to fire up Passenger (passenger start in your Radiant folder), visit your server name, and have it redirected.

This Passenger instance will run as long as you are connected, or as long as the machine stays up (whichever ends first). But that won’t do for a production webserver…

Making Your Passenger Get Up, And Stay Up (OS X)

Figuring out what command to give launchd

This goal is not as obvious as it might seem. We want a Passenger Standalone instance to be up all the time, including after machine restarts. So, how do we best do this?

In the past, for demonstration purposes, I’ve SSHed into a server, fired up GNU Screen, ran passenger, then detected the screen. GNU Screen will keep the SSH socket open (from the server’s perspective, anyway), and thus Passenger. This solution works, but it’s a hack.

Ideally I want to keep Passenger up without this hack, or other similar “poll based” monitoring methods.

Launchd to the rescue.

Here’s how to get that up:

  1. Create a rvm wrapper:

    $ rvm wrapper RUBY@GEMLIST radiant_site

    Will create ~/.rvm/bin/radiant_site_ruby

    So if you’re running ree with your gemset name “radiant_site”

    $ rvm wrapper ree@radiant_site radiant_site

    Which creates a Ruby named radiant_site_ruby.

  2. Find out where your passenger is:

    which passenger

Your command to start up your Rails site is an amalgamation of these three things and the path to your Rails root:

/Users/aias/.rvm/bin/radiant_site_ruby /Users/aias/.rvm/gems/ruby-1.8.7-p299@radiant_site/bin/passenger start PATH TO SITE -e production

Try this command on the command line before pouring it into a launchd script.

Pouring it into Launchd

Launchd has two interesting features which we’ll use here:

  1. KeepAlive: Launchd will make sure your progress stays up, restarting if neccisary
  2. UserName: run the command as a particular user

My Launchd file is here:

Save your version of this file to /Library/LaunchDaemons/ – you want this to launch even if your user is not logged in.

Load the file with: sudo launchctl load /Library/LaunchDaemons/FILE NAME

Launchd Debugging Notes

  1. launchd scripts must be owned by root:wheel. (Lingon does not save files this way)
  2. Use StandardErrorPath and StandardOutPath to debug these. Note that the files must exist first, and be writable by root. These are amazingly useful files to have to see what your job is going.
  3. Seriously, you do not want the -d flag for Passenger. (It makes the whole thing not work – launchd has rules about what you can and can’t do in KeepAlive/LaunchDaemon mode)

But what about Passenger Standalone on Linux?

I haven’t tried either of these out, but they look like they would fit the bill.

April 9, 2011

Installing Passenger Standalone — and solutions

Filed under: General Information,ResearchAndDevelopment — Ryan Wilcox @ 12:10 am

Intro: What is Passenger, and why I want to use it

I seriously want to love Passenger Standalone, I really do. Certain client projects of mine could use the increased speed, and I’d love to use Passenger Standalone for production deploys too (more on that in a future article).

But it seems like I’m running into every problem under the sun installing this thing. Here are my solutions to these problems.

Problems & Solutions

I ran passenger start and it downloads and compiles things, then fails with sh: line 0: cd: ext/libev/: No such file or directory

Thanks to this issue on the Passenger Google Code site I found out my CDPATH needed to contain “.”.

Solution:

$ export CDPATH=.:$CDPATH and redo passenger start

I ran passenger start, it downloads and compiled everything, now I get: the following error during startup:
Unable to start the Phusion Passenger logging agent because its executable
(....passenger/standalone/3.0.6...-macosx-10.6/support/agents/PassengerLoggingAgent) doesn't exist

Thanks to this Google Group conversation the best way to deal with this issue is to:

  1. $ passenger package-runtime. This will create a passenger-standalone folder in your current directory, with a folder (3.0.6…macosx-10.6). This folder will have a support.tar.gz and a nginx-0.8.5.4.tar.gz file.
  2. Note where it says the file is missing from (standalone/3.0.6…-macosx-10.6, in the case above), and go ~/.passenger/(that directory). Trash the support folder that’s there, and extract the support.tar.gz file (from step 1) in this directory

Conclusion

That took a lot more debugging than it should have (or, to be fair, than it has in the past). But I eventually got Passenger Standalone running. Now that yack is shaved, I hope this blog entry helps others with similar issues

February 21, 2011

WD Billing Strategies: Or why start date and end dates are SO critical

Filed under: General Information,Meta-Company — Ryan Wilcox @ 10:02 pm

Since starting Wilcox Development Solutions I’ve understood two things:

  1. Programmer time is expensive – indeed, prohibitive – to most people or companies.
  2. When people buy expensive things they want to know where their money went. Even at the grocery store you get a big long receipt with your purchase, and programmer time will set you back many grocery trips.
  3. People want accountability – people want to know what I’m working on so they know I’m not just billing them for watching Battlestar Galactica.
  4. Stop times and end times are important, not just durations. Transparency is a big thing for me, so if a client (say) doesn’t want to pay for any hours I work after midnight I can take those hours off their bill and stop working late nights for them. Turns out there’s an Even Better Reason for this too, but I’ll get to that

Once, on a project one of my coworkers was accused of punching in for 8 hours but only working six. (The rational: “Because you always punch in 8 hours, and nobody is that consistent on this project – there’s always other stuff, or lunch breaks or whatever!”).

This guy seems like one of the most honest guys around. Additionally, he seems to me to be machine-like with his consistency and thoroughness, like for example always preferring purity over practicality,. If the guy says he worked 8 hours, he probably did.

Anyway, talking to another coworker, and based on some observations of my own, the “accused”‘s standard MO is to put in 6 hours during the day, but then go home and work 10PM to 12:00 PM. I can confirm this too (kind of) because two or three out of five days during the week I see him on Skype chat, and I’ve chatted (occasionally) about project stuff at those late hours.

So this guy gets accused of timesheet games. He has records that prove his innocence, and some statistics to back up his claims of 95%+ 8 hour days. Luckily.

The client’s time keeping system for this project simply has duration. Yes, I’ve been complaining about this for an entire two years, every chance I get. Luckily whatever system my coworker’s company uses internally must track more information that just duration.

If I had been accused of such a thing I would have literally laughed in the client’s face and thrown 8 pages (times 12 months) worth of invoices at them and let them drown in it.

Yes, Virginia, I bill by the month, and me working full time on a project for one month for you will land you a 7-10 page invoice at the end of that month. No, I don’t think this is excessive, and I will figuratively tear your invoices to shreds, via user stories that your invoice is failing. (To those curious out there: Yes, I am available for hire in this area of meta-consulting.)

The moral of the story: always record start date, end date and duration on your invoices. If you don’t record this you will get burnt. If you have to use another time system to keep track of client hours do not do it unless the system has start and end date, and multiple session support (As a user story now: “As a user I should be able to enter my morning work, then take a non-billable break of arbitrary duration for lunch, then enter my afternoon then take a break of arbitrary duration and possibly enter hours for the evening).

For a while there I was also running SLife, on the paranoid assumption that the start, end and duration dates on the invoice might not be enough, and that the client would want to see proof. (There’s also TrackTime, which does a similar thing). I’d be able to answer the question: “Yes, I was using my computer during those times, and here are the applications and windows I accessed – happy now?”

I don’t run SLife any more ($10/month wasn’t exactly worth it just to keep the paranoid person in me quiet). But for some people, in some situations, this is a life-saver, I’m sure.

Anyway, I even wrote my own time tracking system (sessionnotes.appspot.com) because time tracking systems at the time (2008) didn’t have everything I needed. Now I use sessionnotes and Harvest (Starting early 2010, Harvest now does start/end dates and Very Long Descriptions: two things that are critical for me).

I also assume that either the computer will crash when I’m taking notes, or I’ll want a paper back up copy somewhere also, so I keep handwritten notes of everything I do during the day. These approximately mirror what goes into sessionnotes (sessionnotes has better spelling and less drawings of stick men in hats in it, but it’s the same thing.)

Yes, this is petty crap. But transparency shouldn’t be hard at all, and this is one of the ways you can get easy wins without doing much at all.

February 20, 2011

Introducing Scrum Status

Filed under: General Information,ResearchAndDevelopment — Ryan Wilcox @ 3:07 pm

One of my projects has a problem: while we all try to be in the office for scrum, sometimes we can’t all be. Maybe one person is in the car and can’t talk, maybe another person is on the subway… maybe another person has the day off (but the team needs to know their status).

So I started working on a website to take care of these things, and used this team as guinea pigs. Today I announced this site to the world: Scrum Status

Now we have a centralized place to see the entire team’s statuses, easily. Likewise, it’s easy to make an entry for the day while on the go – scrum status works pretty well on iPhone (even though it hasn’t been specifically tweaked for it).

In the spirit of startup launches I’m launching early, to get feedback. Early testing with my team has ironed out the critical bugs, but now I’m announcing this to the world.

Scrum Status runs on Google App Engine, so I don’t have to worry about scaling issues: 1 person could hit the site, or 5,000 – Google App Engine should be able to handle it.

Interested in technical details? The entire project is open source, and the README has a lot of information about the tech involved: Scrum Status on Bitbucket.

February 1, 2011

Lesson from W. Edward Deming on software

Filed under: General Information — Ryan Wilcox @ 10:45 pm

Over this weekend I read some of W. Edward Deming’s Out Of Crisis. Deming was a man credited with the success Japanese industry had after World War II. I’m 100 pages into the book and have already pulled out much information

Saturday I read:

… Next day, in one of his plants, a superintentant showed me two pieces of a certain item from two different suppliers, same item number and both beautifully made; both met specifications, yet they were sufficiently different for one to be useable, the other one usable only with costly rework, a heavy loss to the plant

In short: context is important, and understanding context more so.

A similar thing just happened to me.

A few months ago I created some import functionality for a client – import a file and add it to some table in the database. So we followed the spec exactly: wrote that file to a table. Writing to that table in isolation, because the specs (even through digging and talking with the customer) specified only that.

Today I find out that this table actually is a major reference table that needs to tie into the app in two different places. This discovery means we have to revisit that import even though we implemented it exactly per specification the first time.

Not knowing the context caused extra work and added delay to a software project that was already under schedule risk

Lesson here: Your consultant wants both of you to succeed. As much as you can, provide context for where this functionality will fit in the bigger picture. In exchange for that you’ll get better more quality product in the end, and probably your product will ship faster, and have fewer bugs, than without that context.

January 25, 2011

Does your project have a tools directory?

Filed under: General Information,Meta — Ryan Wilcox @ 1:33 pm

My title here at Wilcox Development Solutions is Owner, Chief Engineer and Master Toolsmith. The last part is because I love making tools that make other people faster.

In every project we have the project itself, but I also encourage you to create a tools folder in your project, to keep items that might not add business value, but add programmer value.

Some examples:

  • On a Rails project I have a tools folder that contains a precommit hook for failing a commit if there are debugger statements left in
  • On a wxWidgets project I’ve put “package up and release this app” tools here. (Actually, we had three folders: tools, tools-osx, and tools-generic, as this was a cross-platform app)
  • On a larger project, where we were building a product line, I had scripts to build certain apps, or every app. This was especially helpful as individual apps in the project transitioned away from CodeWarrior to Xcode

I believe having a public place for tools encourages developers to share their workflow and efficiency tools with the group, ultimately making the team more efficient as a whole.

July 12, 2010

The Date/Scope Debate

Filed under: General Information — Ryan Wilcox @ 3:13 pm

I’m going to start a new practice. Before I even do an estimate for a client, I’m going to ask:

Which is more important to you: having it done by a certain date, or having all your features 100% complete?

Two extremes: I’m dealing with a client right now that has a very firm, but internal, sense of when they want my current project done at. I’ve dealt with clients in the past who don’t care when it’s done, just as long as its perfect when we ship.

These are both legitimate decisions.

In the former case, if your ship date is set, then your development team needs to know it. It can even be in the form of sprints: “how many sprints do we have until ship date: 3, or 6?”. This is important, because it gives me a sense of urgency: how hard do I have to push back when scope increases, how conscious do I have to be about my time?. How closely does the dev team’s PM have to monitor developer’s feelings of progress?

It’s the old Parkinson’s Law in affect: if you tell me 6 sprints I’ll take 6 sprints: I might spend a few hours refactoring something here, or shaving a yack. Stuff that needs to be done, of course, but if you tell me 3 sprints I’ll work that much harder to ignore hairy yacks (“Ok, whatever, it’s taking too much time: I don’t need to fix it now, just get it up and leave a TODO item for later”).

A time limit also forces an agile team to think about pushing back. As scope increases on you, or additional bugs get entered by QA, this deadline determines your behavior. In short: how hard do you (or the direct management of your development team) have to watch your engineering time?

Now, a scope increase could be implicit as well as explicit. Implicit scope increases take the form of: “When we went to implement this, our initial estimates said it would be easy, but it’s now consumed 3 engineer/days… not so easy after all, actually”. Explicit increases take the form of new requirements, and (to an extent) bug reports.

With a firm date you can sit down with your client and have a discussion about these things, approach it in an agile way. Do they still want that “small thing that grew to 3 engineer/days”? Or would they rather get started on implementing different functionality?

Both of these answers are right, in different contexts. That’s why the conversation is there. With a deadline, especially a tight one, you need to make sure you are evaluating from sprint to sprint and making decisions agilely, based on the changing gestalt of the landscape.

I thought there’s a quote, but I can’t seem to find it now, from some military general, about how a plan only lasts a few minutes in actual battle. Same here, in the software development world.

Yes, these are just two sides of the Project Triangle. I’m assuming, for this article, that your team size/cost is set. But maybe it’s not (bully for you!)

July 5, 2010

Django app/sample

Filed under: General Information,ResearchAndDevelopment — Ryan Wilcox @ 11:56 pm

So I decided to switch things around and write a sample application in Django. I started a simple project management / bug tracker / projects-have-many-todo-items app.

Hopefully in the near future I can spend some more time on this example app, for example actually finishing up more than just the project level screens :)

Find it at (in a Mercurial repository on bitbucket:) wd_project_dashboard.

June 27, 2010

My Base Rails Setup

Filed under: General Information — Ryan Wilcox @ 10:14 pm

I’ve been working with Rails for 2 years now, and I’ve developed a collection of tools I really like. I’m going to share these with you (eventually I’ll make a Rails template for them, but not now).

Normal Application Stack

  • will_paginate
  • formtastic: this really cuts back on the amount of HTML I have to write, and, having the input type defaulted from the column type is nice
    I can also script/generate form $MODEL, which is awesome.
  • DataMapper: I haven’t had a project to use this on yet, but this is my preferred ORM.
  • sentient_user: I very often need to know who the current user is when I’m in my models.

    Yes, I can avoid some of this by querying through the controllers, but sometimes you just need to know who your current user is.

    Instead of worrying about what the latest fashion is in the Rails community, I’ll just let some common code.

  • show_for. Formtastic for show actions.
  • My annotate_models port: I finally have an annotate_models that works exactly like I want it too. That’s the great thing about Github: the easy network graph.
  • Inherited Resources: I really don’t like code in my app that just boilerplate (especially auto generated boilerplate). The boilerplate just gets in the way if I have to customize the controller or view, and just needlessly brings up the line count if you don’t.
  • Data Migration: I don’t like putting data changes in the migrations, and db/seed.rb sucks if you add data to it (you have to be careful to not add duplicates!). Data migration gives us a way to add data to a production system in the same way we might add/chage schema

Inherited Resources is great, especially when the controller is in an early stage of development or an admin controller that might not matter.

If the code’s not there I won’t have to maintain it at some point in the future.

On the testing front

  • shoulda. I like the simplicity of Test::Unit, but I don’t like typing def test_the_object_should_error_when_the_date_is_invalid_my_fingers_are_bleeding_ackk. Shoulda context and should blocks makes this a lot easier.
  • timecop. I love Timecop.
  • machinist. The tagline says it all: fixtures aren’t fun, Machinist is.

Utilities

  • Mailtrap: enough of mail server to handle ActionMailer communications… and log them to a file.
  • rr: easy mocking framework
  • jQuery’s timeago plugin: I hate websites that say “created 5 minutes ago.” Do you mean 5 minutes from now, or 5 minutes from when I last refreshed the page? Use some Javascript to avoid this question
  • BlueprintCSS
  • utility_belt: make IRB way more useful.

Hopefully there’s one or two new things in here for you to add to your Rails setup!

March 6, 2010

A Simple Write-to-a-file Turbogears 2 Logger

Filed under: General Information,Turbogears — Ryan Wilcox @ 1:22 am

Turbogears uses Python’s logger module to perform logging operations. This has an advantage (it uses Python’s logger module) and an disadvantage (it uses Python’s logger module).

Be that as it may, here is the simplest configuration possible for you to log to a file (by default TG logs to your STDOUT device, which might not actually be what you want).

In (environment).ini (aka: development.ini)

Note: The format of logging section of this file follows the format laid down in the logging configuration file format section of the standard library documentation.

[handlers]
keys = console, file # added file (line was: "keys = console")

[logger_MY_TG_APP_NAME] # will be named whatever your TG app is named
level = DEBUG
handlers = file
qualname = MY_TG_APP_NAME

[handler_file] # added this section
class = FileHandler
args = ('MY_TG_APP_NAME/logs/foobar-debug.log', 'a+')
level = NOTSET
formatter = generic

Accessing this in your code


import logging
log = logging.getLogger("MY_TG_APP_NAME")

# .... code here ....

log.info("hi!")

« Previous PageNext Page »