Tuesday, December 27, 2011

Toolchain

I work for startups, mostly on web-based software and services (SaaS). Tools are everywhere, and we need to get a lot done. Fast. Our tools have to work for us, not against us. The right tool makes life a lot easier and gets features out the door faster. The wrong tool slows the whole team down, wastes money, and wrecks morale.

So what do I use?

Before I talk about specific tools, let me lay a bit of groundwork. When I'm working for a client, I frequently use their toolchain. When I'm running engineering, we frequently use the toolchain I describe below. Most of the projects I work on are web or mobile web applications, or software APIs (think SaaS).  We're almost always a distributed team, and we usually use some variation of agile methodologies (SCRUM-like or kanban-like). The important part to take away is that we're generally working on multiple things at once, we try to keep those things small, and we push new features or changes into production when they're ready, without waiting for a defined release cycle.

Feature Tracking:
Product: PivotalTracker
Cost/Level: $18/month will hold until your dev team passes 5 people, then $50/month
Summary: I'm not in love with this one. It works pretty well, but there are a few features I wish it had, like: (1) distinguishing between done and deployed; and (2) a UI that doesn't feel so darn squished.
Other candidates worth considering:
  • Jira: Too heavy and too pricey. Annoying to configure, and really encourages excessive time spent on tracking ("ooh! pretty graphics!"). It's useful if you have nervous and overbearing management involved.
  • Lighthouse: Good for very small projects with savvy business types. Good email and source code integration and very simple, but little to no workflow or enforcement of procedures.
  • Trajectory: I've heard good things, but not used it. Somewhat niche.
Bug Tracking:
Just use the same thing you're using for feature tracking. Don't overthink it.

Source Code Management
Product: GitHub
Cost/Level: $12/month will hold until your dev team passes 5 people, then $22/month
Summary: It's hosted. It's stable. It's Git, which lets the dev team do amazing things.
Other candidates worth considering: Just use GitHub

Hosting
I can't make a single recommendation for hosting, since it depends so much on your product and your team. There are a couple of scenarios that might make sense:
  • If your goal is cheap, you're on Rails, and you don't have a sysadmin type on staff, use Heroku.
  • If your goal is reliability and you can do your own administration, use Amazon AWS and put your database on an RDS instance.
Product: Heroku
Cost/Level: varies based on usage, but the add-ons add up
Summary: This is cheap and it's the easiest scaling I've ever done. It's also well configured, which  makes a big difference. Big downsides: frequent downtimes (especially if you use the shared database), and it will only backup once an hour, so data loss is a possibility. Also, use the kumade gem if you're using heroku. The deployment model of heroku alone is pretty bad; kumade helps.

Product: Amazon AWS + RDS
Cost/Level: varies based on usage
Summary: This lets you start small and will scale with you. It's also very reliable (and can be made more reliable if you have more money to spend). Interaction with Amazon is a solved problem, so scaling and deployment are simple problems. Big downsides: you have to do your own configuration, which means you need some sysadmin skills to set it up.

Development Environment
This one varies based on your product and personal experience. I mostly work on web apps, and my preferences look like this: Ruby on Rails, TextMate (vim is fine, too), cucumber, rspec. As long as there ARE build and testing tools in place, let the dev team pick what they like.

Build and Deployment
This is another one based on product and personal preferences. Just make sure there IS one. Oh, and the deployment should be something that's run automatically from the build system. The answer here is a tool, not a manual process.

That's my stack. If I've forgotten an element, let me know and I'll be happy to talk about it. If you disagree or recommend a different tool, let me know. I'm always curious to see if there are better tools for my toolkit!

Always And Never Usually Aren't Either

One of the quirks of coming to software development through test and through business is the healthy fear it provides of absolutes. Things that should "never" be true or are "always" bad turn out to be true on rare occasions or sometimes beneficial. This holds in the software we write. For example, you should never  use the singleton pattern because it adds a hidden global dependency.... But a logger should can be a singleton because you really want to unify logging into one place that's configured by multiple things. This also holds for practices and procedures. For example, we should never use a test script.... But perhaps there is a situation where that would be useful, like in an automated smoke test where the script is in the form of code. There are no best practices at all ever... But I have yet to find anyone who thinks that keeping code in source control is a bad idea (maybe its a best practice!). Regardless of the topic within software, any time you hear an absolute - always or never - be suspicious. When someone talks in absolutes, there's usually a reason they're speaking with such exaggeration. Sometimes they're simply naive. Sometimes they're insecure and trying to hide it. Sometimes they're just seeking attention through dogmatic pronouncements. No matter the cause, be smarter than that. Notice the absolute statements, recognize that they say more about the speaker than about the statement, and move on. Things that seem absolute probably aren't.

Thursday, December 22, 2011

Describe the Unusual

Documentation is a part of my job, like many engineers. I write documentation for end users, training material, documentation for other developers (API docs, anyone?), bug reports... all sorts of things. And like many documentation creators, I can talk for a long time about some of these things.

Saying too much is a very good way to frustrate your audience. They don't want to know everything; they can't absorb it all and they lose the important parts. So follow the cardinal rule of documentation:

Describe the unusual.

Let's assume for the moment that documentation is about describing interaction. It attempts to explain to the reader how to successfully work with the system - whether that interaction is through an API, a GUI, or whatever - and how to understand what the system is doing (i.e., error states, message meanings, etc).

Describing interactions is a huge thing, which is why it's so easy to write a whole lot of documentation. But that's the wrong thing to do. The truth is, most of the time you can assume some basic knowledge, and just describe what's different.

For example, I'm working right now on a logging module for a system. The system right now does ad hoc logging; each component logs in its own way. My logging module will provide centralized logging so we get consistency in log level, storage location, format, etc. When I'm documenting this, what can I assume, and what should I write about?

My audience is other developers who work for this company. They pretty much understand the system, the language, and general development concepts. Great!

So I describe the things that are unusual:

  • instantiating this (custom) logger I wrote
  • requirements around uniqueness and sharing of loggers (class instances)
  • whether it is thread safe (yes) and process safe (no)
  • deployment requirements and the configuration format, for the IT guy
  • log size and rotation rules, which I got from the IT guy
I don't describe the things that developers generally expect from logging:
  • the existence of log rotation and aging
  • when to log at various levels (DEBUG vs INFO, etc)
  • the format of the log entry
I can skip what people already know, which makes the documentation much shorter and makes the important parts more readily apparent. It's easier for the consumers to read and much more likely to be actually useful.

So when you have to document something, whether it's a multi-day tutorial or a simple comment describing how to use a method, focus on the things that make it unique. Describe the unusual.

Tuesday, December 20, 2011

Breathing Room

One of the fun parts about the end of the year is how many big initiatives tend to pile up. The culmination of a big project - whether that's a new website, a major refactoring, a release, or something else -  often results in a release. In many ways this makes sense. It is, after all, the end of the year, which is arbitrary but a really common breakpoint and time to assess accomplishments. It's also a relatively quiet time, with many people on vacations, so usage tends to be relatively light (except if you're retail!).

But.

(Ha! I always say "but".)

There's a catch. Big projects are fine, and putting them out at the end of the year makes sense in many settings. The risk is in trying to put out too many too quickly. Any big project comes with risk. When you do many of them at once, you compound your risk, and make it harder to figure out what broke when you're troubleshooting.

If at all possible, give your big projects some breathing room. Push them out and then go work on something small for a brief period. It doesn't have to be long - a few hours or so - but it'll make life a lot easier. Use the breathing period to:

  • get a new baseline of system behavior and identify behaviors and patterns caused by your large change
  • reflect on what you've done and tie up any loose ends
  • review the next big change in light of the new system behavior, configuration, etc.; does anything need to change?
Breathing room is good for humans and good for systems. Take it, if you can.

Thursday, December 15, 2011

Dependency and Redundancy

My software is, of course, perfect. (HA! but go with it). The trouble is that the software I write uses other software; I have external dependencies. For example, Textaurant uses Heroku for hosting, Twilio for text messaging, New Relic for monitoring, and Airbrake for error aggregation.


There are a several good reasons to have external dependencies like these, including:
  • Development speed. Using providers for pieces of the solution lets us focus on the core value we provide rather than the common.
  • Better reliability. People who specialize in monitoring, for example (like New Relic), are going to be a lot better at monitoring than someone who doesn't think about this all the time.
But.... there is a big downside.

When your external provider goes away, you're in big trouble. If Heroku goes down, my app is unavailable. If Twilio goes away, I won't be sending any text messages. It doesn't matter that the outage is on the service provider end - to my customers, it's just the application they use not doing what it's supposed to. And that's my problem.

So we have dependencies, which are really useful and also introduce risk. What can we do about it?

Lots.

Let's take a simple example. My hosting provider had an outage on December 3rd that took down our application. What could have prevented us from being unavailable, even as Heroku was having a No Good Very Bad Day? We could:
  1. Add a second hosting provider, writing into a shared database (or db cluster). Properly load balanced, the hosting provider who was not affected could simply have taken over all hosting duties.
  2. Fail over to a secondary hosting provider as soon as we realize we're down, again using a shared database or database cluster.
  3. Use local data storage in the browser to allow users to keep working. It wouldn't provide full functionality, but it would have given us 85%+ of our features, which is a lot better than simply being down.
There are two common themes running through these options: redundancy and cost. We can increase redundancy.... as long as we're willing to pay for it. How far you go toward ensuring redundancy is tempered by how much time and money you're willing to spend. In the end, it's up to you and to your particular needs. Just consider your dependencies... before they go down and make you consider them in a panic!

Tuesday, December 13, 2011

Selective Vacation

It's never a good time to take time off. I'm pretty terrible at vacations in general. And yet, faithful readers will notice that I haven't written here in a week, which is a long time for me - that's practically a vacation!

One of the consequences of being a consultant and having several clients it that someone's almost always on a deadline. If client A just got through a big push (and is now taking a collective few days to decompress), that's frequently when client B is just facing down a big deadline. It makes scheduling vacations... tricky.

So I take selective vacations.

A selective vacation is a vacation... from part of my life. This past week it was a vacation from my blog. Sometimes it's a vacation from a client, or not starting a contract immediately. Sometimes it's a vacation from writing articles. Sometimes it's a vacation from cooking dinner! And sometimes it's a vacation from being home - I spent last week in California visiting family and working.

There are a lot of benefits to a vacation: a change in routine can spark new ideas; getting away can stave off any potential burnout; health benefits accrue from lowering stress on vacation; fun vacation photos or stories spark conversations with your coworkers. At least for me, vacations also provide an appreciation of routine (I do like my routine!). I get a lot of these benefits from a selective vacation - it sparks creativity, and gets me out of a routine temporarily. I also find it very relaxing - not only do I not have all the normal pressures and deadlines, but I'm doing enough work that I don't get stressed over missing important client calls or deadlines.

The point is that if you're like me and find it hard to stop everything and take a vacation, then don't. Take a selective vacation. It offers a lot of the same benefits of a real vacation, but it's a lot more doable.

Tuesday, December 6, 2011

Your Software's Personality

Software is a very cold and abstract thing, really. It's nothing we can touch or interact with. So we tend to anthropomorphize it. We think some software is cute, and other software is a workhorse, and still other software tries hard.

For example, Twitter is cute. It has fun little error messages. It features pastels, lots of colors, a good amount of white space, and cheerful graphics.

At the other end of the spectrum, Photoshop is a workhorse program. It has eight bazillion buttons and menus (I know, I counted), and it feels really powerful if you can just get it to do what you want. Of course, getting a program that big to do what you want is something like knowing how to use a workhorse - it takes practice!

As software engineers, designers, product managers, etc., we can help shape our software's personality. We can encourage users to think our software is fun, or simple, or dense and informative - all by the decisions we make while implementing it.

The first step is to decide what kind of personality we want. Are we building a consumer game that should be fun and irreverent? Are we building statistical analysis software where we want it to be prescient and nonintrusive? Are we building software for highly trained users, where we want it to be very consistent and provide hints without getting in the user's way?

Once we understand what our personality is, then we can find ways to express that personality through software. Consider:

  • The tone of the text
  • Graphics and colors
  • Layout - how dense?
  • The presence (and intrusiveness) of help and guidance
  • the workflows - wizards or menus? how short or long?
Your users will give your software a personality - it's up to you to make it the personality you want.