
When you start reading this book, you will quickly understand that the authors are affiliated with IBM. This is nothing wrong per se, but this seems to influence too much the vision that the book proposes, ignoring approaches proposed by others. Including “iterative” in the title seems here to be only a marketing trick used to make it catchy. They don’t give you a precise definition of “iterative”, saying rather than it is a “modern method” (Tom Gilb was talking about evolutionary development 30 years ago) and that iterative management is result-based rather than activity-based. The difference between iteration and increment is not discussed. The IBM bias is visible when they state for instance that RUP is a “well accepted benchmark of modern iterative process”.
The beginning of the book describes the development process, providing a two pages description of COCOMO in the middle of it, and proposes way to improve it. The solutions focus mainly on an initial emphasis on architecture and modeling (naturally it is UML with some tools) associated with the recommendation for code reuse or component integration. I was hoping to find more useful material in the part dealing with “practical measurement for software engineering”. However the material is arranged around RUP phases and I found only one metric formula in the 50 pages devoted to this topic. There is some interesting content in this part, but it is only very high level.
This short book is close to be only a white paper for the IBM Rational Unified Process approach. It contains some interesting material for a software development manager wanting to think about introducing metrics, but its biased IBM approach and lack of directly useful content make it awkward for the experienced development professionals.
Reference
“The Economics of Iterative Software Development”, Walker Royce, Kurt Bittner and Mike Perrow, Addison-Wesley, 171 pages, IBSN 978-0-321-50935-2
Get more details on this book or buy it on amazon.com
Get more details on this book or buy it on amazon.co.uk
Quotes
The most significant way to improve economic results is usually to achieve a software solution with the minimum amount of human-generated material. Our experience shows that managing scope and raising the level of abstraction through component-based technology and service-oriented architectures are the highest leverage techniques that make a difference
External stakeholders, including customers and users, cannot expect initial deliveries to perform up to specifications, to be complete, to be fully reliable, or to have end-target levels of quality or performance.


Collaboration: The New Duct Tape
Thomas M. Cagley Jr.
The economic crisis of the past few years has caused organizations great and small to actively chase innovation. Just what exactly innovation is and how it can be measured is are hotly debated topics. Even though everyone wants to be an innovator, we will ignore the definition of innovation for the time being and focus on one of the primary tools being leverage in the pursuit of innovation, collaboration. We will focus on collaboration because done correctly; collaboration is the duct tape of the business world.
Collaboration is typically defined as two or more people working together to solve a common problem or in pursuit of a common goal. Two components of the definition get to the crux of what makes collaboration work. The first is the phrase “two or more people” because you can’t collaborate by yourself. Without different points of view much of the power of the technique is lost. Second is the phrase, “common problem” or “common goal”. The common goal acts as the focusing mechanism for the overall process. Combining these two concepts means that collaboration works through social interactions focused on a common mission. Done correctly collaborative efforts deliver synergy, addresses complexity and fosters involvement.
The makeup of the team is a major component of the success of any collaboration. Rogers and Hammerstein combined scores and lyrics into fantastic songs, creating something greater than the simple sum of the parts. Great sports teams attain championships when they combine complementary skills which allow them to tackle problems that they are not capable of addressing individually. In brainstorming we are taught to build on the ideas of others; to dovetail ideas. Combining and building on the ideas and thoughts of the team is synergy.
Businesses don’t create collaborative teams to tackle the simple problems. When was the last time you formed a collaborative team to decide when you were going for lunch? Never? But there probably was a group created (hopefully collaborative) to decide where the entire office would go for the last holiday lunch. Collaboration is a reflection of the maxim that two heads are better than one (on different people). Many times multiple points of view are required to solve problems that can’t be easily described or solved individually. Collaborative groups allow problems to be viewed from multiple points of view which allows the team to describe problems and solutions in a more robust manner which is one technique for dealing with complexity.
Collaboration can used to build buy in for the solutions that are generated. Naomi Karten in her book, Changing How You Manage and Communicate Change, said “that even a minimal sense of control can go a long way towards easing the stress that people feel.” Collaboration is one means of providing a means for participation yielding a sense of control. Each voice on the team is a representative of a constituency that is being voiced as the solution is crafted. As part of implementing the solution it must be expected that the individual representatives support and sell the solution to their constituencies.
Part 2 –Attributes of Collaborative Teams
I'm posting this from Moscone West, the site of Google I/O 2010. Some things that it may be useful to know:
The official hash tag is #io2010
The keynotes will be live-blogged all over the place (thus, not here) and also live-streamed on YouTube.
If you're mad because you couldn't get a ticket, we're sorry, but you're not alone. We have filled Moscone West to the very absolute splitting-at-the-seams max. There are a ton of Googlers who couldn't get in.

Things have already started; above is our own Roman Nurik giving the first Android session at the pre-IO Bootcamp.

Above are the signs over the Android part of the main gathering area. There are many tantalizing display cases and tabletops; gleaming and empty now, but not for long.
Meta-BloggingThursday is the big Android day at Google I/O. There will be announcements. We're going to try to use this blog to deliver more depth and perspective than you can expect from an executive on a stage in a keynote. So we've lined up a whole lot of blog posts; more than any human could be expected to read in a day.
The plan is to have a couple of posts on Thursday summarizing and highlighting what we think are probably the big-news stories. Then we'll have more detailed technical pieces every other day or so for the next couple of weeks, filling in the details behind the announcements. It's heart-warming how eager the engineers are to tell the world about what they've been building, and it makes me happy to facilitate the process.
There are other Google blogs that are going to be working hard too, telling the other stories coming out of this gathering. We'll post some links to things that seem particularly newsworthy, either to the world in general or to the Android comunity in particular.
Stay tuned!
Back in February I started work on integrating Yahoo’s FireEagle location service into Geomium and I ran into a problems with Python 2.5. Using Steve Marshall’s Python library the included test.py script was working perfectly with Python2.6, but when running with Python2.5 I’d get back an “Invalid OAuth signature error”.
I posted the problem to the OAuth user group but didn’t get any response. I got in touch with Yahoo. After quite a bit of back and forth we finally figured out the problem, which I’m posting here to try and save others from months of frustration!
The Yahoo guys noticed that with Python2.5 the HTTP host header was being sent through as as “fireeagle.yahooapis.com:443″, whereas 2.6 sends “fireeagle.yahooapis.com”. The inclusion of the port results in an invalid OAuth signature, because the signature is generated assuming the port isn’t included. I dug into the Python2.5 httplib code and came across this:
813 if self.port == HTTP_PORT:
814 self.putheader('Host', host_enc)
815 else:
816 self.putheader('Host', "%s:%s" % (host_enc, self.port))
In Python 2.6 the comparison on line 813 is done with self.default_port instead of HTTP_PORT, which prevents the port from being added with HTTPS requests. I noticed that later on in the code that if you pass in your own host header it prevents one being created for you:
875 def _send_request(self, method, url, body, headers):
876 # honour explicitly requested Host: and Accept-Encoding headers
877 header_names = dict.fromkeys([k.lower() for k in headers])
878 skips = {}
879 if 'host' in header_names:
880 skips['skip_host'] = 1
So the fix turns out to be really simple – explicitly set the http header. That’s exactly what I’ve done in my fork of the fireeagle library (see the fix). I’ve also sent a push request, so hopefully this fix will make it back into the original library. Thanks to Arnab Nandi and Anand S from Yahoo for helping to debug things their end.
Unicorn's been a topic I've been interested in learning about for a while now; numerous Engine Yard customers and developer friends use it, love it, and recommend it. Thankfully, the opportunity to do so recently presented itself. I spent some time poking around free resources looking for answers to my questions, and it wasn't as easy as I'd hoped... so I decided to go straight to the source.
First, I spent a bunch of time going over the Unicorn README file. While comprehensive, when I was done, I still had questions, so I put them all together, and emailed the Unicorn development team. They were gracious enough to reply with detailed answers to all my questions, and now that I'm in the know, I figured this would be a great resource to share with the rest of you. It's not our usual style of blog post, but it's solid information just the same, in what's hopefully an easily consumable format.
I've organized the questions into topical sections. The topics are: Clients, Debugging, Process Management, Load Balancing, Thread-safety, Rack support and Rack wrapper, Log Files, Binary Upgrades, Forking, Listening Interfaces, Configuration, Asynchronous Transfers, The Binary and Dependencies. There's a lot, so read through it all, or skip straight to the section that interests you.
Clients What are "fast-clients"?Clients that can make full (or close to full) use of the network bandwidth available to the server. Clients on a LAN (or the same host) usually fit this description, as they don't have to trickle data to the server over a slow link.
What's a slow client, by comparison?A client with high latency or limited bandwidth that forces the server to sit idle and wait for data in the request or writable buffer space in the response. Accept filters in FreeBSD and deferred accept in Linux mitigate this problem for slow legitimate clients, but a dedicated attack can still get around those.
Slowloris is perhaps the most prominent example of the damage that could be caused by slow clients, but there have been similar tools like it floating around privately for years, including the Unicorn author's own "David" tool, which he (David) only made public after Slowloris:
Clients that sit around with idle keepalive connections is also huge problem for simple servers like Unicorn (and traditional Apache prefork), so Unicorn does not support keepalive.
The Unicorn author also works on the Rainbows! server, which is designed specifically to handle talking directly to slow clients and high-latency apps (Comet/WebSockets) without nginx in front.
What is a "low-latency, high-bandwidth connection"?Anything on localhost or the local area network that doesn't make the server sit idle, unable to service other requests.
Debugging Can you give me an example of how to debug?Reproducibility is critical to debugging. Processes are inherently simpler, as the process state is always well-defined on a per-request basis and isolated from other requests as much as possible by the OS. One example is to help track down a memory leak related to a specific class of requests:
An non-Rubyist admin noticed that among a pool of workers, some used significantly more memory than other workers. Since the log file format always logged the PID serving each request, they were able to quickly narrow down which endpoints were prone to leaking memory (without even looking at the code).
In a server where requests are all served within the same process, it would've been much harder to narrow down which endpoints were using up memory. In a server where a single process handles multiple clients simultaneously, it would've required thorough inspection of the source code to track down which requests were leaking memory.
Process Management"Unicorn will reap and restart workers that die from broken apps. There's no need to manage multiple processes or ports yourself. Unicorn can spawn and manage any number of worker processes you choose to scale to your backend."
Does that mean that Unicorn doesn't need monit or god?No server needs things like monit or god; it all depends on your comfort level, your app, and your support requirements. It's always possible—albeit unlikely—for the master process to die, but things like monit and god aren't immune to dying, either. Developers use those tools, and similar ones, like Bluepill, with Unicorn.
Load Balancing"Load balancing is done entirely by the operating system kernel. Requests never pile up behind a busy worker process."
So there isn't a mongrel queue issue?No, there no a Mongrel queue issue on a single machine. A single queue is shared across worker processes and the workers only pull off the queue when they're available to do work. There's still a potential queue issue in a cluster behind a load balancer, but the risk is mitigated, since most servers are multicore and run multiple worker processes. The queue is also tunable by specifying the :listen parameter.
Thread-safety Why is thread-safety good?The utility of thread-safety really depends on the particulars of your situation. It gives you much more flexibility with what your app can run, and under ideal conditions, threads are memory efficient and relatively inexpensive. Thus, allowing apps to work with threads is good for experienced programmers.
On the other hand though, making things thread-safe by default can hurt performance in single-threaded situations. Even contention-free locks can end up adding significant overhead due to memory barriers. Both MRI and Python core developers have come to this same conclusion.
Rack Support and Rack Wrapper What rack applications are supported?Pretty much anything that passes Rack::Lint (and sometimes, even a few that don't).
What Ruby on Rails versions does the wrapper support?The manpage says everything 1.2.x to 2.3.x, and there are integration tests for those version.
Log Files"Builtin reopening of all log files in your application via USR1 signal. This allows logrotate to rotate files atomically and quickly via rename instead of the race condition prone and slow copytruncate method."
What is the USR1 signal?USR1 is the first user-defined signal, which usually gives applications the most flexibility in determining what a signal handler for it would do. To send a USR1 signal to Unicorn, use the standard kill(1) command:
kill -USR1 $PROCESS_ID
Nginx also uses the USR1 signal for reopening log files. Most of the signals Unicorn accepts map directly to the nginx ones for ease-of-learning. Unicorn also takes steps to ensure multi-line log entries from one request all stay within the same file.
Binary Upgrades What are binary upgrades?Binary upgrades are upgrades that upgrade Unicorn itself, the version of Ruby, or even any system libraries including the system C library. For users that depend on copy-on-write functionality, it's also the only way to upgrade the application
How do you upgrade?The upgrade procedure is the same as nginx, and is also documented here (bottom of page).
What happens after upgrading?After ensuring the old processes are terminated gracefully (via SIGQUIT), that same code should ensure that the app behaves as expected. If the app is broken, another "upgrade" is required which may involve switching back to a known good version.
Forking What is the preload_app directive?The preload_app directive loads the application before forking workers, so it can share any loaded data structures. By default, workers each load a private copy of their app for out-of-the-box compatibility with existing servers.
What's a use case for using the preload_app directive?preload_app can dramatically speed up startup times. It can also make it easy to share memory across processes when using Ruby Enterprise Edition. REE also uses tcmalloc on some platforms, like Linux, instead of a generic malloc, which improves performance for most server workloads independently of copy-on-write.
Listening Interfaces What's an example configuration for how to set this up and how this can be used for debugging an application?You can set up a worker to listen on a specific address so that you can do things like strace the worker while hitting that address and see what happens. There's a commented out example in here, which is shortened and uncommented here:
after_fork do |server, worker|
# per-process listener ports for debugging/admin/migrations
addr = "127.0.0.1:#{9293 + worker.nr}"
server.listen(addr, :tries => -1, :delay => 5)
end
Normally, strace will slow down a process enough that it usually "loses" when trying to accept() a connection against other workers and it never sees the request.
Configuration Is there a good example configuration to help me get started?The examples here cover many settings, including comments. The simplest case is with preload_app=false. Here's a short example:
worker_processes 16
pid "/path/to/app/shared/pids/unicorn.pid"
stderr_path "/path/to/app/shared/log/unicorn.stderr.log"
stdout_path "/path/to/app/shared/log/unicorn.stdout.log"
In contrast, preload_app=true can significantly complicate things, as it requires disconnecting/reconnecting to the database and other connections to avoid unintended resource sharing. All configuration settings are documented in the RDoc of the Unicorn::Configurator class.
In addition to Unicorn::Configurator settings, there's also the rackup config file (usually config.ru) used by all Rack applications independently of the underlying server. There's also system/kernel tuning, which the Unicorn documentation touches on here.
The Binary What is the unicorn executable? What is the unicorn_rails executable?The unicorn executable is a Rack-only tool modeled after Rack's "rackup" and is recommended for Rack applications. unicorn_rails was made to be an easier transition for users of pre-Rack versions of Rails. The manpage encourages Rails 3 users to use plain unicorn instead.
What's the difference?From the unicorn_rails manpage, some conventions of unicorn_rails are modeled after script/server found in Rails. It creates directories under "tmp" like script/server and the -E/--environment switch sets RAILS_ENV instead of RACK_ENV.
Dependencies Are there any dependencies? Gems, system packages, etc.Rack is the only Gem Unicorn currently depends on. Unicorn does not set hard dependencies on any released version of Rack. Unicorn depends on MRI 1.8 or 1.9 on a Unix-like platform. There have been commits to make the C/Ragel HTTP parser work with Rubinius, but there have been some other issues in the pure Ruby code. Building from git requires Ragel (but the distributed source tarball/gems do not). The project does not distribute precompiled binaries.
Unicorn uses RDoc for most of the documentation and John MacFarlane's Pandoc (a Haskell tool) for the Markdown manpages. Pandoc was the most prominent Markdown to manpage converter at the time, as Ryan Tomayko's ronn had not appeared when the manpages did.
What are the requirements? Operating system, ram, etc.Most POSIX-like platforms are supported. Unicorn depends on a bunch of Unix-y things like fork(), the ability to share file descriptors with children, signals, pipes, unlinked open files, etc...
Unicorn has been deployed to and tested on various Linux distros heavily. The Unicorn mailing list has gotten reports and patches for OpenBSD compatibility, too, so that should work. Unicorn does not depend on any exotic system calls not provided natively by MRI.
RAM usage depends heavily on the application/libraries, version of Ruby, word size of the architecture, and number of worker processes configured. It shouldn't take significantly more or less than any other Ruby web server.
ConclusionI didn't start out with a specific problem, more like a void in my knowledge base, and now that that void is gone, I'm pretty pleased with the robust capabilities of Unicorn. It's not going to be the tool-of-choice for every use case, but clearly, it'll do wonders in a lot of them. As always, leave questions and comments here!
Manymoon is a free social productivity tool that helps teams manage and share projects, tasks and conversations. We became part of the Google Apps Marketplace at launch and have seen tremendous early success. Over 1,000 new businesses sign up each week, making us one of the top apps in the Marketplace. Below are some of our tips for building a successful app:
Last week I spoke a test manager who told me with his shoulders hanging low, that his test department had grown substantially, but hardly had developed. He realized that he was confronted with his own limits on his knowledge, experience and to a certain extent on his own personality. The organization had expressed her satisfaction with the test department on more than one occasion, but this was not the feedback he had hoped for. He struggled for a time with the question “what is the next step?”, not knowing the answer.
It troubled him that his own organization didn’t have an answer to that question. “Am I ahead of the rest of the organization?”
Talking the matter over we realized that the thing which makes you ‘big’ also keeps you ‘small’. To break through this dilemma you have to break through your own believes, pick up unconventional approaches and start experimenting with new methods. In that respect a test manager should not only be concerned with the test process, but also with his own personal development.
Where to start? How do you address today’s problems and at the same time develop towards future needs….as an individual, department and as an organization? Or is this question too far beyond the realm of testing?
We took a big sip of our coffee, noticed it had become undrinkable…. and started to ravage our brains and established some shared guidelines which might be helpful:
We could have come up with many more or different `guidelines`…and probably will. We started our contemplative moment with “What is the next step?”….We realized that in this case the question itself is more valuable than the answer will ever be. It helps you to stay ahead, personally and professionally.
The bottom line is that you contemplate about your profession and personal development!
Do you have any personal guidelines you would like to share? What do you do to break through organizational limits or personal boundaries when it comes to the test profession?
Many thanks to Otto Vos, he has written this nice post! Follow him at twitter.com/ottovos, motivate him to be more active at twitter.