In most projects I have been on as a consultant, getting the right environments together was an incredibly consuming task on several people with too much to worry about already: project management, senior techies and the ones responsible for keeping the legacy environments running.
Recently, the idea of getting an example minimal application deployed as soon as possible during the project lifecycle has been banded about a bit as one of the things that could’ve made my last project run smoother (as always, hindsight is always 20-20). Then, one of my colleagues (either Graham Brooks or Sam Newman, but I could be mistaken) brought up a simple and perfect analogy for it, found in The Pragmatic Programmer: a tracer bullet.
Tracer ammunition (tracers) are special bullets that are modified to accept a small pyrotechnic charge in their base. Ignited upon firing, the composition burns very brightly, making the projectile visible to the naked eye. This enables the shooter to follow the bullet trajectory relative to the target in order to make corrections to his aim.
Tracer bullets are used during the daytime as well, but their importance is heightened severely at night: when shooting in the dark, being able to see the trajectory is crucial, since other clues — such as surrounding objects being hit — are harder to recognize and do not provide quick enough feedback for the shooter to be able to adjust his aim in a timely fashion.
Since most software projects are, in a way or another, shooting in the dark, it makes sense to create a special type of application deployment that increases the visibility of the deployments coming after it.
This application does not need to have any features, besides painting an accurate picture of what the real application (coming up in the next few deployments, hopefully) will behave like. A few interesting things to analyze:
- System environment: is the PATH set properly? Are the versions of compilers, interpreters and runtimes correct? Is there enough memory and storage space?
- Library dependencies: are all the dynamically linked libraries available and in the correct versions? What’s the overhead of a particular choice of framework or data mapping strategy in memory consumption and performance?
- Interactions with other legacy systems: are they available in the correct version? Is the application authorized to talk to them? Can they be contacted reliably and at the performance levels desired, or is there a network issue that needs to be solved?
- Performance: how many users of the application (once it’s deployed) can we tolerate? What are the expected response times? Under load, what are the bottlenecks?
These questions do not necessarily have to be answered by a monolithic tracer bullet application. In my view, they’re more like deployment spikes: once they answer a question and the team learns from them, they can be thrown away or reused, but there’s no obligation to build on a previous one if doing so adds noise to the measurements.