<?xml version='1.0' encoding='utf-8' ?>
<feed xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>/dev/mull</title>
  <generator uri='http://effectif.com/nesta'>Nesta</generator>
  <id>tag:devmull.net,2009:/</id>
  <link href='http://devmull.net/articles.xml' rel='self' />
  <link href='http://devmull.net' rel='alternate' />
  <subtitle type='text'>The mull device</subtitle>
  <updated>2011-10-26T00:00:00+00:00</updated>
  <author>
    <name>Steven Shingler</name>
  </author>
  <entry>
    <title>The Developer Sales Funnel</title>
    <link href='http://devmull.net/developer-sales-funnel' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2011-10-26:/developer-sales-funnel</id>
    <content type='html'>
            &lt;p&gt;Yesterday, I attended Mashery's &lt;a href=&quot;http://apiconference.com&quot;&gt;Business API Conference&lt;/a&gt; which focussed on the evolving nature of APIs and how businesses use them.&lt;/p&gt;
            
            &lt;p&gt;Businesses like Twilio, Datasift and Qwerly use their website purely as a lead generation tool. The API is the revenue generator. Twilio CEO &lt;a href=&quot;http://www.twilio.com/company&quot;&gt;Jeff Lawson&lt;/a&gt; made some great points about the connection between developers as consumers of APIs and what developers are looking for in an API.&lt;/p&gt;
            
            &lt;p&gt;Awareness of a new API in a business often comes from developers, rather than from the marketing or commercial side of the business. This grass roots traction is an important aspect of an API only business. If developers are becoming customers in that way, there must be a developer sales funnel.&lt;/p&gt;
            
            &lt;p&gt;The traditional sales funnel looks like this:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;Marketing =&amp;gt; Visitor =&amp;gt; Signup =&amp;gt; Pay&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;It is a model to track the progression of people engaging with your business from their first contact, to finally becoming a customer. It is a funnel because you have less people engaging with each step. (Utopia would be a sales cylinder.) Once you've got someone to the bottom of the funnel, attention changes to retaining them as a customer. That's the holy grail of the subscription business model - but customer retention is a whole other subject.&lt;/p&gt;
            
            &lt;p&gt;A funnel where developers are the customers has the same headline points as the tradition sales funnel, but the details behind each step are both interesting and subtle. We have to take into account here that developers are usually smart people, perhaps with a touch of cynicism, and are highly sensitive to marketing material.&lt;/p&gt;
            
            &lt;h3&gt;Marketing&lt;/h3&gt;
            
            &lt;p&gt;A developer will hear about a new API from grass roots sources, rather than from a sales email, phone call or glossy brochure. Typically, that will be from another developer, perhaps at a Hacker News &lt;a href=&quot;http://www.meetup.com/HNLondon/&quot;&gt;meetup&lt;/a&gt;, or from an online source like
            Stack Overflow or &lt;a href=&quot;http://www.reddit.com/r/programming&quot;&gt;r/programming&lt;/a&gt;. Typically, you'll hear about the same new hotness a few times from different sources before it hits enough of a threshold in your brain to prompt you to properly check it out.&lt;/p&gt;
            
            &lt;h3&gt;Visitor Engagement&lt;/h3&gt;
            
            &lt;p&gt;Once the developer has gone to your website, they'll want to know two things:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;* Can I try it out easily?&amp;#x000A;* What does your API look like? &amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;A developer doesn't want a sales person to reach out to them to learn more about their API needs and budget. They want to know whether it is a RESTful API, whether it uses http properly* and whether they can sign up and get a token easily - just to try it out. So, a clear signup form is important. Good documentation is the channel the developer requires to learn how to actually use the API. Putting effort into clearly written, up to date documentation is well worth it (and unfortunately something many API providers currently fail on) because it is such a key point of decision making for a developer at the start of their engagement with your business.&lt;/p&gt;
            
            &lt;h3&gt;Trial&lt;/h3&gt;
            
            &lt;p&gt;Appealing to developers with modern API interfaces such as JSON over RESTful http calls, rather than hugely verbose SOAP/XML calls will help early adoption. That's because the developer has to write less code to start getting results from the API. Current trends are towards using &lt;a href=&quot;http://devmull.net/articles/a-ruby-client-for-datasift&quot;&gt;WebSockets&lt;/a&gt; which give you bi-directional persistent streaming - great for receiving messages over a long period of time.&lt;/p&gt;
            
            &lt;h3&gt;Pay&lt;/h3&gt;
            
            &lt;p&gt;So, once a developer has tried your API and found it easy to use and useful for their needs - the next stage for them is to start paying for their calls. Perhaps that event happens at the end of a trial period, or after their initial credits have been used. At this point the developer is likely to have to make a case to their business representative about the benefits of the API. A clear pricing model, published openly on your website will aid this part of the sales funnel. Again, requiring a developer to speak to a sales representative presents more of a barrier than an enticement to adoption.&lt;/p&gt;
            
            &lt;p&gt;* &lt;em&gt;Footnote: DELETE is not a GET request.&lt;/em&gt;&lt;/p&gt;
          </content>
    <published>2011-10-26T00:00:00+00:00</published>
    <updated>2011-10-26T00:00:00+00:00</updated>
    <category term='misc'></category>
  </entry>
  <entry>
    <title>Serving Rails apps with Unicorn and Bluepill. Includes Resque.</title>
    <link href='http://devmull.net/articles/unicorn-resque-bluepill' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2011-07-16:/articles/unicorn-resque-bluepill</id>
    <content type='html'>
              &lt;p&gt;At Wordtracker we run four Rails apps in production. Two of those use background jobs with a &lt;a href=&quot;https://github.com/defunkt/resque&quot;&gt;Resque&lt;/a&gt; implementation. We've recently switched to serving them using &lt;a href=&quot;http://unicorn.bogomips.org&quot;&gt;Unicorn&lt;/a&gt;, with &lt;a href=&quot;http://nginx.net&quot;&gt;Nginx&lt;/a&gt; as a proxy. We've found the restart times on deployment to be far quicker and more graceful, which gives us confidence to roll out new features to our customers as soon as they become available.&lt;/p&gt;
              
              &lt;p&gt;I hope the following configuration snippets might be helpful for anyone wanting to serve their Rails applications using Unicorn.&lt;/p&gt;
              
              &lt;p&gt;For the record, we're currently on Rails 3.0.7 with Ruby 1.9.2.&lt;/p&gt;
              
              &lt;p&gt;The forking blocks feel like code, rather than configuration, but they are extremely important if you're running with multiple worker processes:&lt;/p&gt;
              
              &lt;pre&gt;&lt;code&gt;    pid_path = &quot;tmp/pids/unicorn.pid&quot;&amp;#x000A;    listen &quot;*:8031&quot;&amp;#x000A;    worker_processes 8&amp;#x000A;    timeout 30&amp;#x000A;    preload_app true&amp;#x000A;    pid pid_path&amp;#x000A;    stderr_path &quot;log/unicorn-err.log&quot;&amp;#x000A;    stdout_path &quot;log/unicorn-out.log&quot;&amp;#x000A;&amp;#x000A;    before_fork do |server, worker|&amp;#x000A;      ActiveRecord::Base.connection.disconnect!&amp;#x000A;      old_pid_path = &quot;#{pid_path}.oldbin&quot;&amp;#x000A;      if File.exists?(old_pid_path) &amp;amp;&amp;amp; server.pid != old_pid_path&amp;#x000A;        begin&amp;#x000A;          Process.kill(&quot;QUIT&quot;, File.read(old_pid_path).to_i)&amp;#x000A;        rescue Errno::ENOENT, Errno::ESRCH&amp;#x000A;          # someone else did our job for us&amp;#x000A;        end&amp;#x000A;      end&amp;#x000A;    end&amp;#x000A;&amp;#x000A;    after_fork do |server, worker|&amp;#x000A;      ActiveRecord::Base.establish_connection&amp;#x000A;      rails_env = ENV['RAILS_ENV'] || 'production'&amp;#x000A;      worker.user('app', 'app') if Process.euid == 0 &amp;amp;&amp;amp; rails_env == 'production'&amp;#x000A;    end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
              
              &lt;p&gt;We need to monitor our apps together with their Resque background jobs. We're using &lt;a href=&quot;https://github.com/arya/bluepill&quot;&gt;Bluepill&lt;/a&gt; for that:&lt;/p&gt;
              
              &lt;pre&gt;&lt;code&gt;    app_name = 'my-app'&amp;#x000A;    worker_queues = ['my-app'] * 4&amp;#x000A;&amp;#x000A;    rails_env = 'production'&amp;#x000A;    user = 'app'&amp;#x000A;    group = 'app'&amp;#x000A;    rails_root = &quot;/var/apps/my-app/current&quot;&amp;#x000A;    ENV['PATH'] = &quot;/opt/ruby192/bin:#{ENV['PATH']}&quot;&amp;#x000A;&amp;#x000A;    Bluepill.application(app_name) do |app|&amp;#x000A;&amp;#x000A;      app.working_dir = rails_root&amp;#x000A;      app.uid = user&amp;#x000A;      app.gid = group&amp;#x000A;&amp;#x000A;      app.process(&quot;unicorn&quot;) do |process|&amp;#x000A;        process.pid_file = &quot;#{rails_root}/tmp/pids/unicorn.pid&quot;&amp;#x000A;        process.stdout = process.stderr = &quot;#{rails_root}/log/bluepill.log&quot;&amp;#x000A;        process.environment = { 'RAILS_ENV' =&amp;gt; rails_env }&amp;#x000A;&amp;#x000A;        # Unicorn needs to be invoked using a path which includes 'current', &amp;#x000A;        # otherwise it tries to restart with the executable installed in an old release dir (which get cleaned)&amp;#x000A;        process.start_command = &quot;bundle exec #{rails_root}/vendor/bundle/ruby/1.9.1/bin/unicorn -Dc unicorn.rb&quot;&amp;#x000A;        process.stop_command = &quot;kill -QUIT {{PID}}&quot;&amp;#x000A;        process.restart_command = &quot;kill -USR2 {{PID}}&quot;&amp;#x000A;&amp;#x000A;        process.start_grace_time = 30.seconds&amp;#x000A;        process.stop_grace_time = 5.seconds&amp;#x000A;        process.restart_grace_time = 13.seconds&amp;#x000A;      end&amp;#x000A;&amp;#x000A;      if defined?(worker_queues)&amp;#x000A;        worker_queues.each_with_index do |queue_list, i|&amp;#x000A;          app.process(&quot;resque-#{i}&quot;) do |process|&amp;#x000A;            process.group = &quot;resque&quot;&amp;#x000A;&amp;#x000A;            process.pid_file = &quot;#{rails_root}/tmp/pids/resque-#{i}.pid&quot;&amp;#x000A;            process.stdout = process.stderr = &quot;#{rails_root}/log/resque-#{i}.log&quot;&amp;#x000A;            process.environment = {&amp;#x000A;              'RAILS_ENV' =&amp;gt; rails_env, &amp;#x000A;              'QUEUE' =&amp;gt; queue_list&amp;#x000A;            }&amp;#x000A;            process.start_command = &quot;bundle exec rake resque:work&quot;&amp;#x000A;            process.stop_command = &quot;kill -QUIT {{PID}}&quot;&amp;#x000A;            process.daemonize = true&amp;#x000A;          end&amp;#x000A;        end&amp;#x000A;      end&amp;#x000A;    end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
              
              &lt;p&gt;Finally, a bit of Nginx config&lt;/p&gt;
              
              &lt;pre&gt;&lt;code&gt;    root /var/wordtracker/apps/my-app/current/public;&amp;#x000A;    access_log /var/log/nginx/my-app.access.log main;&amp;#x000A;&amp;#x000A;    location / {&amp;#x000A;      try_files $uri @unicorn;&amp;#x000A;      access_log off;&amp;#x000A;      expires 30d;&amp;#x000A;    }&amp;#x000A;    location @unicorn {&amp;#x000A;      proxy_pass http://localhost:8031;&amp;#x000A;      error_log /var/log/nginx/my-app.error.log warn;&amp;#x000A;      include /etc/nginx/nginx-proxy.conf;&amp;#x000A;      proxy_set_header X-Forwarded-Proto https;&amp;#x000A;    }&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
            </content>
    <published>2011-07-16T00:00:00+00:00</published>
    <updated>2011-07-16T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
    <category term='ruby-and-jruby'></category>
  </entry>
  <entry>
    <title>Teams and the art of leadership</title>
    <link href='http://devmull.net/articles/teams-and-leadership' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2011-06-26:/articles/teams-and-leadership</id>
    <content type='html'>
                &lt;p&gt;I recently finished reading Mike Brearley's &quot;The Art of captaincy&quot; (Pub 1985, ISBN-10: 0752261843). Brearley is a former cricketer who led the England cricket team in 31 of his 39 Test matches, winning 17 and losing only 4. He was described by team mates as &quot;having a degree in people&quot; and now works as a leading psychoanalyst. The Art of captaincy, ostensibly about cricket captaincy, transcends sport to become a treatise on teamwork and leadership. When reading it, I realised that many aspects and issues he deals with in the book apply directly to leading a team in disciplines outside sport. For example, Sam Mendes mentions in the foreword that he consulted it when making &quot;American Beauty&quot;.&lt;/p&gt;
                
                &lt;p&gt;I found myself making notes as I went through the book, detailing passages which seemed to apply most directly to my work: leading a team of software developers. Restructuring abstract notes made from Brearley's already terse, clinical writing has been a really interesting challenge. I hope that what follows is of interest to software developers and those trying to lead them.&lt;/p&gt;
                
                &lt;h3&gt;Team sizes&lt;/h3&gt;
                
                &lt;p&gt;A team should be small enough for communication to be simple, for individuality to be maintained and for each team member to know the others well. It is not accidental that sporting teams range from around seven to 15 members. A true group cannot exist with less than that and more becomes a crowd. Two is not a team. They may combine well together, but too much hangs on the individuals and how they happen to get on. Threes tend to divide into a two and a one; fours into two pairs. Five or six people can make a group, but the absence of one or two individuals (e.g. for illness or holiday) makes its identity precarious.&lt;/p&gt;
                
                &lt;h3&gt;Balancing inputs&lt;/h3&gt;
                
                &lt;p&gt;The leader has the benefit of ideas from all sources. If they differ from his, he discovers where the opposition lies, and what form it takes. A leader will be confronted with sometimes intense pressure from the team to fit in with the prevailing or desired emotional mood. These demands may be conscious or unconscious. A leader may be terrorised into an approved set of attitudes. A leader may be pulled into a mood of delinquency or persecution in ways which undermine the performance of the task.&lt;/p&gt;
                
                &lt;h3&gt;Giving feedback&lt;/h3&gt;
                
                &lt;p&gt;Different team members need different forms of praise. Praise offered too freely or too unctuously become devalued. A leader should get to know people's strengths and to learn which sorts of questions to ask of which team members. A leader's input, even in an informal setting, may set creative ideas going, or give a team member a sense of his real value.&lt;/p&gt;
                
                &lt;h3&gt;On team members&lt;/h3&gt;
                
                &lt;p&gt;Team success is the product of personal successes. A person's efforts should be valued by the rest, particularly when their contribution is unglamorous. Team members learn the habit of thinking for themselves and their self-respect is enhanced when their right to be heard is fully accepted and the space given to them to speak helps them formulate good responses.&lt;/p&gt;
                
                &lt;p&gt;A team member feels the benefit of security of being well regarded and confidence to respond to the realistic but challenging standards which are opened up for him. Roles may also restrict and the same role may work well or badly at different times. A team member can fail to value himself enough, leading to diffidence in the team. Individual protagonists take their meaning from, and are strongly influenced by, the group context.&lt;/p&gt;
                
                &lt;h3&gt;Difficulties within a team&lt;/h3&gt;
                
                &lt;p&gt;The atmosphere working in a difficult environment promotes denial. Worries are underplayed and a cynical attitude with an emphasis on efficiency predominates. The outcome is often friction, illness among staff and high levels of mistakes. At times of anxiety and stress the same qualities that have been helpful and vital are inevitably exaggerated or distorted.&lt;/p&gt;
                
                &lt;p&gt;The pull of the team may be into a position that is the opposite of the emotional orientation of those making the demand. The leader may be lassoed into an answering emotional attitude. The pressure may be put on him to become a tyrannical boss who relieves the others of the need to think for themselves. Or he may be required to become passive and cringing before a powerful bullying process predominant in a group at that particular time.&lt;/p&gt;
                
                &lt;p&gt;A way of lessening guilt is to find ways of making others share it or take it on. The outcome of succumbing to such pulls is that the clarity that leaders need to do the job properly has been hijacked. Power now lies with the unconscious group, with the leader only the leader in name. It is hard for someone who is caught up in the turmoil of pulls to see what's going on, much less to be able to understand the forces in play and regain control.&lt;/p&gt;
                
                &lt;h3&gt;On meetings&lt;/h3&gt;
                
                &lt;p&gt;Consultation with team members takes different forms and can be used for different ends. It may merely be the means by which the leader gains technical or practical information on which to base his decision. It may also be the occasion for a decision. Or it may be seen, and used, more as an end in itself, a process of sharing and sorting out feelings, antagonistic or otherwise, within the group. We are right to be skeptical of meetings, but a good team meeting can have the output of a renewed commitment to each other and the side.&lt;/p&gt;
                
                &lt;h3&gt;When things aren't going well&lt;/h3&gt;
                
                &lt;p&gt;If a team member is making silly mistakes all consultation, delicacy of feeling, weighing up of pros and cons need to give way to orders, bluntness, decisiveness. Discipline, will power, effort and guts hang together when under pressure. When these are alone the hallmarks of a leader too much is lacking; they represent a narrow view of human nature and of the possibilities of motivation; but without them, leadership is toothless.&lt;/p&gt;
                
                &lt;p&gt;An insecure team member may find a degree of acceptance by means of assuming the role of court jester, which provided a feeling of security, however precarious. The court jester behaviour can also feed a malicious humour in the rest of the team, who can get on with their own jobs while enjoying vicariously some of the jester's altercations with authority: the group push him further into the part&lt;/p&gt;
                
                &lt;p&gt;Team members may attempt to deal with their doubts by giving up; being passive or depressed - thereby placing a demand on the leader to initiate and take responsibility for everything. This may trigger a leader into becoming bossy and demanding, which perversely the team may have provoked in order to mock.&lt;/p&gt;
                
                &lt;p&gt;One sullen or indolent team member can stand out like a sort thumb - her private interest may conflict with that of the group. Enable the team to reach creative solutions without denying their anxieties. To bring people together in a common task so that they take pleasure in their joint and individual work.&lt;/p&gt;
                
                &lt;h3&gt;Finally: On leaders&lt;/h3&gt;
                
                &lt;p&gt;A team leader is bound to be the recipient of emotional demands and pressures from those she is responsible for. A good leader or manager is interested in what makes people tick, particularly when they seem to be difficult or withdrawn or under-achieving. This kind of interest and attendant attitude, involve the capacity to step back from the hurly-burly of the group. The leader sacrifices the pleasures of being one of the boys, indulging in the dramas of gossip and having a go at the boss.&lt;/p&gt;
                
                &lt;p&gt;The leader is influenced by the team character, but set apart from it, responsible to a degree for moulding it. She is of it, but separate from it, required to be part of it, acting within it whilst overseeing the actions of team members.&lt;/p&gt;
                
                &lt;p&gt;Leaders cannot avoid discomfort - they are required to hold in balance conflicting aims and values. A leader should maintain a reasonable balance herself, but being balanced does not mean being flat, innocuous or bland. No team leader can bring out the best in all team members. Temperamentally, we all respond better to some than to others. There are those who impose on us pressures that make us particularly touchy, or which arouse our own anxieties unduly.&lt;/p&gt;
                
                &lt;p&gt;Leadership calls for complex qualities which are in conflict with each other: Passion and detachment; vision and common-sense. An authoritarian streak and a truly democratic interest in team and points of view. Conviction but also the capacity to not rush in; the ability to tolerate doubt and uncertainty.&lt;/p&gt;
                
                &lt;p&gt;The leader has to be able to take in and think about the anxiety of those who work in the team. It is important to convey that their predicament and anxieties are bearable. If this is done, the team is less likely to resort to damaging states of mind such as defeatism, lack of initiative or complacency. Nor will it be so likely to split into antagonistic factions. This function, of containing anxiety and handing it back in a form that can be thought about, is based on that offered both by our first nurse - the mother to her baby, and subsequently by both parents throughout childhood, adolescence into adulthood.&lt;/p&gt;
              </content>
    <published>2011-06-26T00:00:00+00:00</published>
    <updated>2011-06-26T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
  </entry>
  <entry>
    <title>It's hard to get people to pay for software</title>
    <link href='http://devmull.net/articles/pay-for-software' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2011-04-23:/articles/pay-for-software</id>
    <content type='html'>
                  &lt;p&gt;We've got used to free software. Either we expect it to be free, or (as with Facebook and Gmail) we're happy to use our personal data as currency.&lt;/p&gt;
                  
                  &lt;p&gt;There's a ton of interesting thinking already on the web on the psychological shift that's happened in SAAS (Software as a Service) over the past, say, 5 years, but that isn't really my area - I'm much more interested in building software which people are happy to pay for. I thought it would be interesting to go through a very simple model of financing a new software service from conception to 12 months after launch.&lt;/p&gt;
                  
                  &lt;h3&gt;Why would you pay for software?&lt;/h3&gt;
                  
                  &lt;p&gt;For someone to subscribe to a software product, that software must increase their revenue, productivity or output in some way by a value greater than the cost of the product. That could happen directly: perhaps by giving you some actionable data points which provide an immediate return; or indirectly: for example by making your internal processes more efficient. That assumption alone dictates that paid-for SASS is almost exclusively B2B.&lt;/p&gt;
                  
                  &lt;p&gt;There's tremendous energy amongst software developers right now to create &quot;Product&quot;. There are many threads on Hacker News similar to &lt;a href=&quot;http://news.ycombinator.com/item?id=2471130&quot;&gt;this one&lt;/a&gt;. It details a software developer with, I'm sorry to say, massive naivety - develop a software product and then puzzle over why so few people subscribed. Creating value in software is difficult. Beyond the initial concept you need knowledge of how to reach out to your audience and of course the software development skills to build the product. You'll need design skills to make it look good too.&lt;/p&gt;
                  
                  &lt;h3&gt;Bootstrapping a product - some assumptions&lt;/h3&gt;
                  
                  &lt;p&gt;Let's take a very simple model and work through what's possible. Lets say you're a software developer and you've got a great idea for a software product. To keep things simple, I'll make some assumptions:&lt;/p&gt;
                  
                  &lt;ul&gt;
                  &lt;li&gt;You're convinced that it merits a $20/month subscription and that there's a potentially big market.&lt;/li&gt;
                  &lt;li&gt;You think it'll take 6 months to build the app to a point where it has enough features to launch. (The minimum viable product.)&lt;/li&gt;
                  &lt;li&gt;You can't do it all by yourself. You need a couple of collaborators too. That might be another developer and a designer; or another developer and a customer support/marketing person. Still - lets assume a team of 3.&lt;/li&gt;
                  &lt;li&gt;The three of you are going to give up your day-jobs and work on this full time because you all believe in the project and its potential.&lt;/li&gt;
                  &lt;li&gt;You each need an income of, say, £3000/month to live off. Because you're highly skilled software developers and, well, you're worth it.&lt;/li&gt;
                  &lt;li&gt;Let's not include any other costs, such as rent, incoming data or hosting.&lt;/li&gt;
                  &lt;/ul&gt;
                  
                  
                  &lt;p&gt;I'm sure we can all quibble with those very broad brush assumptions, but I think they're provide us with a good enough baseline to do some projections.&lt;/p&gt;
                  
                  &lt;p&gt;So, you've got to launch day. You've done a fantastic job on getting the word out there, getting people to link to you, sign up to an alpha, a mailing list and generally building up expectation around the general awesomeness of your shiny new product. You've also built the product.&lt;/p&gt;
                  
                  &lt;p&gt;You get 20 paying customers in the first month and you're absolutely stoked. Over the next 12 months the three of you keep working on the product full time: adding more features, responding to customer feedback, fixing bugs, marketing the product, doing PR, speaking at conferences etc. Generally working your asses off.&lt;/p&gt;
                  
                  &lt;h3&gt;Washing up the numbers&lt;/h3&gt;
                  
                  &lt;p&gt;Let's be really positive about projections at this point and say you're going to have 1000 paying customers just 12 months after launch. That would be a wild success, right? Well here's how the numbers play out:&lt;/p&gt;
                  
                  &lt;p&gt;&lt;img src=&quot;/attachments/new-product-numbers.png&quot; title=&quot;Numbers&quot; alt=&quot;picture alt&quot; /&gt;&lt;/p&gt;
                  
                  &lt;p&gt;Oh. 12 months after launch, you're £77,000 in the red. You tipped the £100,000 overdraft point just after launching.&lt;/p&gt;
                  
                  &lt;p&gt;Lets look at the hockey stick view of those numbers:&lt;/p&gt;
                  
                  &lt;p&gt;&lt;img src=&quot;/attachments/new-product-hockey-stick.png&quot; title=&quot;Numbers&quot; alt=&quot;picture alt&quot; /&gt;&lt;/p&gt;
                  
                  &lt;p&gt;We're in a fix here, team. That hockey stick isn't the right way around yet.&lt;/p&gt;
                  
                  &lt;h3&gt;Where from here?&lt;/h3&gt;
                  
                  &lt;p&gt;Apart from the (impossible) task of getting a bank manager to agree a £100,000 overdraft with no collateral, you've got the difficulty of deciding whether to continue with this venture. The flawed assumption that the user count will keep rising linearly could be especially dangerous. If a competitor came along with a bigger market presence that's going to make things very tough. At least if you've got this far you've a fighting chance of increasing your retention rates and gaining new customers.&lt;/p&gt;
                  
                  &lt;p&gt;Of course, it is this predicament that Venture Capitalists try to solve. They throw money at the problem so that you can get to market faster, to learn sooner rather than later whether you're going to be viable in the long term. In backing high numbers of similar companies, they hope to find one hugely successful star, thereby cancelling out the losses from the predominant group of also-rans. In taking VC funding, you sacrifice the lion's share of your business in the hope that the amount you're left with will be worth more in the long term as a result of their investment. That's a whole other business model.&lt;/p&gt;
                  
                  &lt;p&gt;So that's a very quick and simple view of bootstrapping a startup. I deliberately haven't touched on freemium models, conversion/retention rates or launch methods. If you're considering going through this process for your own awesome concept then these are the key parameters:&lt;/p&gt;
                  
                  &lt;ul&gt;
                  &lt;li&gt;How many people are involved?&lt;/li&gt;
                  &lt;li&gt;How little are you willing to pay yourselves?&lt;/li&gt;
                  &lt;li&gt;What is your minimum viable product?&lt;/li&gt;
                  &lt;li&gt;How soon can you launch?&lt;/li&gt;
                  &lt;li&gt;How will people get to hear about you?&lt;/li&gt;
                  &lt;li&gt;Why is your app worth paying for, and how much?&lt;/li&gt;
                  &lt;li&gt;How many subscribers will you be able to attract?&lt;/li&gt;
                  &lt;/ul&gt;
                  
                  
                  &lt;p&gt;That last point is the most important, and that's the one you don't have control over.&lt;/p&gt;
                </content>
    <published>2011-04-23T00:00:00+00:00</published>
    <updated>2011-04-23T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
  </entry>
  <entry>
    <title>Rsift - A Ruby client for Datasift</title>
    <link href='http://devmull.net/articles/a-ruby-client-for-datasift' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2011-01-01:/articles/a-ruby-client-for-datasift</id>
    <content type='html'>
                    &lt;p&gt;&lt;a href=&quot;http://datasift.net&quot;&gt;DataSift&lt;/a&gt; is a &quot;real time social media filtering engine&quot;. They have recently published an  &lt;a href=&quot;http://support.datasift.net/help/kb/rest-api/api-documentation&quot;&gt;API&lt;/a&gt; which allows developers to create and manage &quot;streams&quot;.&lt;/p&gt;
                    
                    &lt;p&gt;A stream in Datasift context is really a filter over their fire-hose of incoming data from Twitter and other media sources. Another part of their API presents a WebSockets implementation for a client to consume data which matches a stream or filter.&lt;/p&gt;
                    
                    &lt;p&gt;The domain of social media curation is very hot right now, so I was very interested to receive a alpha API key to try it out. I work mainly with Ruby, and there wasn't a client out there yet to &quot;wrap&quot; the Datasift API in Ruby, so I thought that writing that gem would be my first step.&lt;/p&gt;
                    
                    &lt;p&gt;The gem can be downloaded from &lt;a href=&quot;https://rubygems.org/gems/rsift&quot;&gt;rubygems&lt;/a&gt; and the code is open source, and available at &lt;a href=&quot;https://github.com/sshingler/rsift&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
                    
                    &lt;p&gt;There are three main facets to the API: Streams, Comments and Data. Their &lt;a href=&quot;http://support.datasift.net/help/kb/rest-api/api-documentation&quot;&gt;API documentation&lt;/a&gt; takes us through the semantics of each object.&lt;/p&gt;
                    
                    &lt;p&gt;My first port of call was to create a mechanism to send an http request to their API endpoint. Interestingly, Datasift are calling it a REST API, but actually every message is a GET - even creating an object such as a new Stream. I decided to create a class for each API Object: Stream, Comment, Data; which each have a Model superclass to instantiate the endpoint url, api key and username.&lt;/p&gt;
                    
                    &lt;p&gt;From there, it was a question of understanding the URL design for each object. I chose to create a method, simply called 'do' on each object which sets up the correct URL for each method and calls it.&lt;/p&gt;
                    
                    &lt;p&gt;I've ended up with this pattern:&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;stream = Rsift::Stream.new(api_url, api_key, username)&amp;#x000A;response = stream.do(&quot;my&quot;) # lists my streams&amp;#x000A;&amp;#x000A;opts = {:stream_id =&amp;gt; &quot;1&quot;}&amp;#x000A;response = @stream.do(&quot;get&quot;, opts) # gets a stream, by id&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;The websockets implementation was new to me. I found the &lt;a href=&quot;https://github.com/igrigorik/em-http-request&quot;&gt;em-http-request&lt;/a&gt; part of EventMachine on github, which made it incredibly easy to implement a client listener to the Datasift websockets server:&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;def self.perform(stream_identifier)&amp;#x000A;  endpoint = &quot;ws://stream.datasift.net:8080/&quot;&amp;#x000A;&amp;#x000A;  EventMachine.run {&amp;#x000A;    http = EventMachine::HttpRequest.new(&amp;#x000A;        &quot;#{endpoint}#{stream_identifier}&quot;).get(:timeout =&amp;gt; 0)&amp;#x000A;&amp;#x000A;    http.callback do&amp;#x000A;      puts &quot;Connected to datasift&quot; &amp;#x000A;    end&amp;#x000A;&amp;#x000A;    http.errback do &amp;#x000A;      raise SocketError.new(&quot;Datasift threw an error&quot;)&amp;#x000A;    end&amp;#x000A;&amp;#x000A;    http.disconnect do&amp;#x000A;       raise SocketDisconnect.new(&quot;Datasift disconnected me.&quot;)&amp;#x000A;    end&amp;#x000A;&amp;#x000A;    http.stream { |msg|&amp;#x000A;      yield msg&amp;#x000A;    }&amp;#x000A;  }&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;This can be called like so:&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;Rsift::Socket.perform(stream_identifier) do |message|&amp;#x000A;  puts message&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;I've added in a couple of custom error classes to handle being disconnected by Datasift, or if the socket throws an error.&lt;/p&gt;
                    
                    &lt;p&gt;Please take a look at the test code on github for more usage examples.&lt;/p&gt;
                    
                    &lt;p&gt;By way of a disclaimer, there are a couple of limitations with the code as it stands right now: (and which I hope to find the time to improve!)&lt;/p&gt;
                    
                    &lt;ul&gt;
                    &lt;li&gt;All calls require credentials to be passed in&lt;/li&gt;
                    &lt;li&gt;All responses are in JSON&lt;/li&gt;
                    &lt;/ul&gt;
                    
                    
                    &lt;p&gt;I'd love to get some feedback, please let me know if you're finding it useful.&lt;/p&gt;
                  </content>
    <published>2011-01-01T00:00:00+00:00</published>
    <updated>2011-01-01T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
    <category term='ruby-and-jruby'></category>
  </entry>
  <entry>
    <title>The Pivot as Prepare, Execute, Listen</title>
    <link href='http://devmull.net/articles/pivot-as-prepare-execute-listen' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2010-11-21:/articles/pivot-as-prepare-execute-listen</id>
    <content type='html'>
                      &lt;p&gt;One of the key principles in lean startup is the Pivot. It has become a bit of a buzzword. The term comes from basketball - keep one foot planted but change direction with the other. The metaphor for business is that you stay grounded in what you've learned whilst testing something new. For example, you might have been offering a monthly subscription product: you could pivot to offering an annual subscription instead, or as well as the monthly.&lt;/p&gt;
                      
                      &lt;p&gt;As I've been reading about Pivots, I realised I had met the pattern before in a quite different context.&lt;/p&gt;
                      
                      &lt;p&gt;Before I was involved in tech, I was a musician. I studied Double Bass at the Royal Academy of Music and played professionally for four years after graduating. Between 1996 and 2000 I was lucky enough to play with the Philharmonia Orchestra, London Symphony Orchestra, Royal Philharmonic Orchestra, the BBC Symphony Orchestra and the Halle Orchestra. I was invited to play at the Salzburg Festival and record for &lt;a href=&quot;http://www.amazon.co.uk/Messiaen-Saint-Fran%C3%A7ois-dAssise-Olivier/dp/B00000JSAO/ref=sr_1_6?ie=UTF8&amp;amp;qid=1290416456&amp;amp;sr=8-6&quot;&gt;Deutsche Grammophon&lt;/a&gt; and &lt;a href=&quot;http://www.amazon.co.uk/Mahler-Tiffin-School-Boys-Choir/dp/B00018BOL0/ref=sr_1_4?ie=UTF8&amp;amp;qid=1290416480&amp;amp;sr=8-4&quot;&gt;Phillips&lt;/a&gt; at Abbey Road studios, London.&lt;/p&gt;
                      
                      &lt;p&gt;The principle double bass of the Philharmonia is &lt;a href=&quot;http://www.neiltarlton.com/&quot;&gt;Neil Tarlton&lt;/a&gt;. He taught me about the &quot;Prepare, Execute, Listen&quot; pattern of practise. A musician working on a piece practises by breaking the piece down, phrase by phrase. For each phrase, he'll have a concept of how he wants it to sound: his interpretation of the phrase.&lt;/p&gt;
                      
                      &lt;p&gt;This form of practising is a loop of:&lt;/p&gt;
                      
                      &lt;ul&gt;
                      &lt;li&gt;Preparing by refreshing your concept for the phrase in your mind.&lt;/li&gt;
                      &lt;li&gt;Executing it.&lt;/li&gt;
                      &lt;li&gt;Testing the results against the imagining you originally had, by listening.&lt;/li&gt;
                      &lt;/ul&gt;
                      
                      
                      &lt;p&gt;You may find that you wish to evolve your original idea, perhaps because your interpretation has evolved or to work around a technical difficulty. To me, that's incredibly similar to the concept of pivoting.&lt;/p&gt;
                      
                      &lt;p&gt;As another point of interest, there's something I've noticed which is very different about the tech industry to the music profession. Back in 1997, when I was working with Neil, he published a book of double bass bowing exercises based on the famous Czech violinist Ševčík's exercises for the violin which were first published in 1880. A quick dance around Wikipedia shows that &lt;a href=&quot;http://en.wikipedia.org/wiki/Otakar_%C5%A0ev%C4%8D%C3%ADk&quot;&gt;Ševčík&lt;/a&gt; was taught by &lt;a href=&quot;http://en.wikipedia.org/wiki/Anton%C3%ADn_Bennewitz&quot;&gt;Bennewitz&lt;/a&gt;, who was taught by &lt;a href=&quot;http://en.wikipedia.org/wiki/Giovanni_Battista_Viotti&quot;&gt;Viotti&lt;/a&gt;, who was taught by &lt;a href=&quot;http://en.wikipedia.org/wiki/Gaetano_Pugnani&quot;&gt;Pugnani&lt;/a&gt;, who was taught by &lt;a href=&quot;http://en.wikipedia.org/wiki/Giuseppe_Tartini&quot;&gt;Tartini&lt;/a&gt;.&lt;/p&gt;
                      
                      &lt;p&gt;Tartini (1692-1770) is still well known in classical music circles today, partly for being the first person to play one of Stradivari's violins but mainly for writing fiendishly difficult violin music. The most famous piece he wrote was the Devil's trill, which I notice has &lt;a href=&quot;http://www.last.fm/music/Giuseppe+Tartini/_/Devil's+Trill+Sonata&quot;&gt;4,919 scrobbles&lt;/a&gt; at the time of writing.&lt;/p&gt;
                      
                      &lt;p&gt;My point is that there's a direct lineage of pedagogy between Tarlton and Tartini which covers almost 300 years. To a musician that's completely normal. A violinist playing the Devil's trill today has the same challenges as in 1750 or 2350. They may even be using the same instrument to play it. In tech, however, this doesn't really exist. Of course I understand why it doesn't exist, and I know that we have Babbage, Lovelace and Turing; more recently Knuth and Stallman (to name a few) as pedagogues of a sort, but the speed of evolution of technology means that we're doing very different things in our work today, than they were. I find that the tech industry is largely populated by young people who can be very sure of themselves: &quot;Hey, we've been doing this for ten years now!&quot; The vibrancy and energy around the startup movement is infectious and engaging, but there's sometimes a tendency towards very black and white views that 'X' is right and 'Y' is wrong. I think we miss much from not having the pedagogy of an older profession and the respect which is inherent in it.&lt;/p&gt;
                    </content>
    <published>2010-11-21T00:00:00+00:00</published>
    <updated>2010-11-21T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
  </entry>
  <entry>
    <title>Running background jobs with Resque</title>
    <link href='http://devmull.net/articles/resque-implementation-walkthrough' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2010-11-03:/articles/resque-implementation-walkthrough</id>
    <content type='html'>
                        &lt;p&gt;Our users at Wordtracker search for keywords and linking domains many thousands of times each day. We run the majority of these searches as &quot;background jobs&quot; to maintain a good user experience.&lt;/p&gt;
                        
                        &lt;p&gt;We'd developed an in-house system written in Ruby and Sinatra for running these jobs, but the robustness and error reporting wasn't as good as we wanted. I decided to take a look at the &lt;a href=&quot;http://github.com/antirez/redis&quot;&gt;Redis&lt;/a&gt; backed &lt;a href=&quot;http://github.com/defunkt/resque&quot;&gt;Resque&lt;/a&gt; (pron. res-queue |ˈreskyoō|) to see whether it would work well for us.&lt;/p&gt;
                        
                        &lt;p&gt;The first thing to understand when looking at a background job runner like Resque, is the aspects of the process you can hand off and the aspects which you still have to take responsibility for within your application.&lt;/p&gt;
                        
                        &lt;p&gt;To work this out, here's the process flow from a Wordtracker search:&lt;/p&gt;
                        
                        &lt;ul&gt;
                        &lt;li&gt;A user hits a search button somewhere on one of our tools.&lt;/li&gt;
                        &lt;li&gt;We check that no job is currently running, for that search type, for that user.&lt;/li&gt;
                        &lt;li&gt;We start the job. (It is at this point that we use Resque to fork into the background process).&lt;/li&gt;
                        &lt;li&gt;The job runs.&lt;/li&gt;
                        &lt;li&gt;The user sees the results.&lt;/li&gt;
                        &lt;li&gt;We clean up the job and archive it.&lt;/li&gt;
                        &lt;/ul&gt;
                        
                        
                        &lt;p&gt;So, the application has to keep track of all jobs - particularly the state a job is in. Resque is only responsible for the actual running of a job.&lt;/p&gt;
                        
                        &lt;p&gt;Lets break down the resque part of the process:&lt;/p&gt;
                        
                        &lt;p&gt;After doing the &quot;check&quot; mentioned above, we drop into the run method on the Job model, which looks like this:&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;def self.run(user_id, name, args = {})&amp;#x000A;  job = Job.create!(:user_id =&amp;gt; user_id, :name =&amp;gt; name, :state =&amp;gt; &quot;new&quot;)&amp;#x000A;  Resque.enqueue(Jobs.const_get(name), user_id, args)&amp;#x000A;  job&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;The enqueue method is where we fork to Resque. The name of the job that's passed into that method matches one of the class names which are Resque jobs. We've put all our Resque job classes in a file lib/jobs.rb. For example, we have a job called &quot;MetricsList&quot;, which will be passed in as a name, and match a class like this:&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;class MetricsUnsavedList &amp;lt; ResqueJob&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;The other parameters are the id of the user who kicked the job off, and a hash of job-specific options. It is a common idiom in Ruby to present arguments as a hash when the contents of the hash might vary and to initialise an empty hash to make the parameter optional.&lt;/p&gt;
                        
                        &lt;p&gt;A Resque class must respond to the perform method and set the queue name. Because there are many different types of search a user can do using Wordtracker, we decided to create a ResqueJob class to &lt;a href=&quot;http://en.wikipedia.org/wiki/Don't_repeat_yourself&quot;&gt;DRY&lt;/a&gt; up common aspects of job handling - those that happen before and after the actual business of running the job. For this transactional pattern, yielding inside a block is helpful, we've wrapped a while_updating_job_status method inside each perform call to handle these functions:&lt;/p&gt;
                        
                        &lt;ul&gt;
                        &lt;li&gt;name the job&lt;/li&gt;
                        &lt;li&gt;set it to a running state&lt;/li&gt;
                        &lt;li&gt;if we're still runnning, set to complete&lt;/li&gt;
                        &lt;li&gt;handle any errors&lt;/li&gt;
                        &lt;/ul&gt;
                        
                        
                        &lt;p&gt;Here's what that looks like:&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;def self.while_updating_job_status(user_id)&amp;#x000A;  job_name = self.name.split(&quot;::&quot;)[-1]&amp;#x000A;  @job = Job.find_by_user_id_and_name(user_id, job_name)&amp;#x000A;  @job.update_attribute(:state, &quot;running&quot;) if @job.state == &quot;new&quot;&amp;#x000A;  begin&amp;#x000A;    yield&amp;#x000A;    if @job.state == &quot;running&quot;&amp;#x000A;      @job.update_attribute(:state, &quot;complete&quot;)&amp;#x000A;    end&amp;#x000A;  rescue Exception =&amp;gt; e&amp;#x000A;    handle_job_error(e.message)&amp;#x000A;    raise&amp;#x000A;  end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;The reason for the funky self.name.split(&quot;::&quot;)[-1] is because we needed the namespace of the classname to be dropped - can anyone think of a better way of doing that?&lt;/p&gt;
                        
                        &lt;p&gt;Then, the perform call inside the MetricsList class looks like this:&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;def self.perform(user_id, args)&amp;#x000A;  while_updating_job_status(user_id) do&amp;#x000A;    # actual search code goes here&amp;#x000A;  end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;The reason for the generic exception handling is that the Resque jobs (obviously) happen inside a different process, so errors won't be passed back directly to our main application which started the job. To get around this, we chose to add a message attribute on the Job model and set the state of the job to error. handle_job_error is also called at any point in the main body of the perform method where we think there's a chance an error might be thrown and we want to handle it in a specific way.&lt;/p&gt;
                        
                        &lt;p&gt;We're very happy with our Resque implementation. Since going live a couple of months ago, it has run almost a million searches with a failure rate of less than 1%.&lt;/p&gt;
                      </content>
    <published>2010-11-03T00:00:00+00:00</published>
    <updated>2010-11-03T00:00:00+00:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
    <category term='ruby-and-jruby'></category>
  </entry>
  <entry>
    <title>Lean Startup London reviewed</title>
    <link href='http://devmull.net/articles/lean-startup-london-reviewed' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2010-10-25:/articles/lean-startup-london-reviewed</id>
    <content type='html'>
                          &lt;p&gt;A couple of weeks ago, I attended a @TechHubFriday event: Eric Ries on The Lean Startup.&lt;/p&gt;
                          
                          &lt;p&gt;Eric is the creator of the Lean Startup methodology and blogs at &lt;a href=&quot;http://www.startuplessonslearned.com/&quot;&gt;Startup Lessons Learned&lt;/a&gt;.&lt;/p&gt;
                          
                          &lt;p&gt;Eric began with an interesting definition of a startup company: &quot;A startup is a human institution designed to deliver a new product or service under conditions of extreme uncertainty.&quot; It has nothing to do with company size or industry sector. Interestingly, this differs from the &quot;two guys in a garage&quot; model, which is probably the mainstream media's impression of a startup.&lt;/p&gt;
                          
                          &lt;p&gt;There's a strong tendency in startup culture to eat your own dog food and scratch your own itch, but it is important to not just ask the question &quot;can we build it? (for us)&quot; but &quot;should we build it? (for others)&quot;. The goal is to create an institution, not just a product.&lt;/p&gt;
                          
                          &lt;p&gt;The &quot;dog food&quot; paradigm raises its head again when choosing the next feature to work on. It is so easy for someone who's invested a lot of energy and emotion in a project to be in a mindset where their opinions seem like the right idea. This flow is a familar path: I really want it =&gt; I really think it is needed =&gt; I think it is a fact. Eric spoke of the &quot;reality distortion field&quot; failing to kick in at this point of the planning process. That thing you want may not actually be true - there may not be lots of other people like you who need that thing.&lt;/p&gt;
                          
                          &lt;p&gt;There's a lot of talk amongst VC/startup community about &quot;pivots&quot;. It has become a bit of a buzzword. The term comes from basketball - keep one foot planted but change direction with the other. For a young company, the metaphor is the ability to stay grounded in what we've learned but quickly respond to changing conditions.&lt;/p&gt;
                          
                          &lt;p&gt;Pivots are insights into how your business is doing. I think in a way, they're another way of thinking about the output of an iteration. Ries warned that it can be difficult to pivot when you're having modest success, that it is difficult to tell the difference between the value creating activities and the wasteful ones. Another trap which we fall into is that it is easy to spend far too long arguing about whether to do a piece of work, where our options are actually quite simple: Do it and fail, not do it and fail, do it and succeed, not do it and succeed.&lt;/p&gt;
                          
                          &lt;p&gt;Eric gave us some choice quotes about the waterfall process:&lt;/p&gt;
                          
                          &lt;ul&gt;
                          &lt;li&gt;Traditional management practices, such as waterfall, were excellent for basic manufacturing process fail now that we have material abundance.&lt;/li&gt;
                          &lt;li&gt;In waterfall, people are not incentivised to do their best work.&lt;/li&gt;
                          &lt;li&gt;The lucky waterfall projects are the ones which come in way over budget and way over time, most fail.&lt;/li&gt;
                          &lt;/ul&gt;
                          
                          
                          &lt;p&gt;Something I thought was particularly useful about the talk, was Eric's ability to deliver bad news in a balanced way. Here's some of his thinking on why so many startups fail:&lt;/p&gt;
                          
                          &lt;p&gt;A lot of startups find themselves in a position where they're treading water. There may be some turnover, some small profit, they're still consuming resources and employees, and generally everyone thinks it might just pull up. The people working there still believe in it despite the plane losing altitude. We have this idea that pouring more effort into such a business is a good idea, because of the emotion and energy we've already sunk into it.&lt;/p&gt;
                          
                          &lt;p&gt;The founder is often the last person to notice the change - everyone else has already moved on, but the founder is never in a fireable position.&lt;/p&gt;
                          
                          &lt;p&gt;Lack of customer and market knowledge is partly accountable for the current epidemic of failure in the industry. We've got better at using metrics from log files or database queries to inform our decisions, but that's really just compensating for a deficiency that we don't get to know our customers any more.&lt;/p&gt;
                          
                          &lt;p&gt;It was a great talk - there was a lot of content I haven't covered here, but other attendees have blogged about the event &lt;a href=&quot;http://andysinclair.wordpress.com/2010/10/19/eric-ries-touches-down-at-techhub&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://theupgroup.wordpress.com/2010/10/18/review-of-techhub-fri-16th-october-a-talk-by-eric-ries-on-the-lean-start-up/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
                        </content>
    <published>2010-10-25T10:24:00+01:00</published>
    <updated>2010-10-25T10:24:00+01:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
  </entry>
  <entry>
    <title>Launching using Agile.</title>
    <link href='http://devmull.net/articles/launching-using-agile' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2010-09-28:/articles/launching-using-agile</id>
    <content type='html'>
                            &lt;p&gt;We've just used agile methodologies to launch a new product, &lt;a href=&quot;http://www.wordtracker.com/linkbuilder&quot;&gt;Link Builder&lt;/a&gt; at &lt;a href=&quot;http://www.wordtracker.com&quot;&gt;Wordtracker&lt;/a&gt;. We had to build the app and get to market quickly. That meant defining a 'viable product' and launching with fewer features than we would ideally have liked. It would prove to be crucial to gain traction and avoid falling behind our competitors.&lt;/p&gt;
                            
                            &lt;p&gt;Link Builder is an app which allows you to analyse the link footprint of your competitors' websites and manage link building campaigns to drive traffic to your website.&lt;/p&gt;
                            
                            &lt;p&gt;The return on investment over time between waterfall and agile release plans can be seen in my sketch below. The jagged line for Agile shows a lower investment risk in getting to market, and an earlier revenue stream from real customers. The revenue is re-invested in polishing the app through successive iterations:&lt;/p&gt;
                            
                            &lt;p&gt;&lt;img src=&quot;/attachments/hockey-stick.jpg&quot; title=&quot;Agile versus Waterfall release graph&quot; alt=&quot;picture alt&quot; /&gt;&lt;/p&gt;
                            
                            &lt;p&gt;The product eventually reaches the same point as the traditional 'hockey stick' line: but with less cost, earlier revenue and valuable feedback from customers that should create a superior application.&lt;/p&gt;
                            
                            &lt;p&gt;There's nothing we do at Wordtracker to diverge from well documented standard Agile methodology, but the most important aspects of the &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;Agile manifesto&lt;/a&gt; are not the well trodden paths of daily standups, pair programming or &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;TDD&lt;/a&gt;, but the subtle challenges of human interaction.&lt;/p&gt;
                            
                            &lt;p&gt;&quot;People over processes&quot; goes out the cry, but too often the agendas and egos of the people involved in designing an app can dominate an implementation where they shouldn't. Agile Methodologies give us some structure and methods to help neutralise those dangers and connect software development to business. I'd like to cover the three aspects which have been important to us in launching Link Builder - the internal customer, iterations and estimating.&lt;/p&gt;
                            
                            &lt;p&gt;Internal Customer: Having someone in &lt;a href=&quot;http://en.wikipedia.org/wiki/Internal_customer&quot;&gt;this role&lt;/a&gt; who knows the problem domain inside out helps hugely. This person can forge a clear roadmap of features which should give the greatest return to a user and clearly communicate the business goals and processes of the software to the developers. It is so important to give the internal customer the respect and space to do his job. Trusting the priority of features, and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;domain specific language&lt;/a&gt; he'll choose for the tool will be good. That is to say: Good enough to launch - any decision can be changed. The clarity and precision a good internal customer brings to the planning &quot;game&quot; hugely decreases the cost of that meeting and gives a developer the confidence only to query a call which jolts her sensibilities.&lt;/p&gt;
                            
                            &lt;p&gt;Iterations: Our iterations are fortnightly, starting on a Thursday. This means that we're only committing to business tasks for two weeks at a time. Rhythm is a vital aspect of productivity, and the iteration start point and weekends are the biggest cadences of an iteration's rhythm. It therefore makes sense not to have them meet. The brevity of an iteration gives us the ability to be very flexible when responding to our users' needs, or the needs of the internal customer. We frequently don't end up implementing what we thought we should a month prior - because it is no longer the most important thing to work on in the present tense. At the end of an iteration, we've found it really helpful to make a short screencast showing off the features we've just made. It helps everyone, especially the customer services team keep in touch with what new features we're about give our users. Also, we try to roll out new features only at the end of an iteration, again so we're all in touch with the timing of new features.&lt;/p&gt;
                            
                            &lt;p&gt;Estimating: There's much debate in Agile circles on the subject of &quot;story points&quot;. &lt;a href=&quot;http://www.pragprog.com/titles/jtrap/the-agile-samurai&quot;&gt;The Agile Samurai&lt;/a&gt;, recently released by the Pragmatic Programmers covers this subject with eloquence. At Wordtracker we've chosen to express our estimations in terms of &quot;Ideal Days&quot;. Commercial people could hardly care less about development methodologies, and will lose interest quickly if you try to tell them about an abstract points system when they ask how long something will take to deliver. Ideal days, however, can be explained very easily: &quot;It is how long we think it'll take if everything goes really well - it is a sunny day scenario.&quot;&lt;/p&gt;
                            
                            &lt;p&gt;By using Agile methodologies we were able to launch Link Builder in a short time scale. Showing the app initially only to people who have bought from us before, got us some fantastic feedback which told us that we're going in the right direction. We're continuing to add the right features - two weeks at a time.&lt;/p&gt;
                          </content>
    <published>2010-09-28T10:24:00+01:00</published>
    <updated>2010-09-28T10:24:00+01:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
  </entry>
  <entry>
    <title>A review of Leancamp</title>
    <link href='http://devmull.net/articles/leancamp-review' rel='alternate' type='text/html' />
    <id>tag:devmull.net,2010-05-12:/articles/leancamp-review</id>
    <content type='html'>
                              &lt;p&gt;A couple of days ago I attended an Unconfernce called &lt;a href=&quot;http://register.leanca.mp/notify/&quot;&gt;Leancamp&lt;/a&gt;.&lt;/p&gt;
                              
                              &lt;p&gt;My main reason for going was that David Heinemeier Hansson - the creator of RubyOnRails and co-author of Getting Real and Rework was speaking.&lt;/p&gt;
                              
                              &lt;p&gt;First, some definitions:
                              &lt;a href=&quot;http://en.wikipedia.org/wiki/Lean_manufacturing&quot;&gt;Lean&lt;/a&gt; is a production practice that considers the expenditure of resources for any goal other than the creation of value for the end customer to be wasteful, and thus a target for elimination.
                              It is currently trending in the world of software as a way of furthering the principles of agile development as a methodology to connect software development with business.&lt;/p&gt;
                              
                              &lt;p&gt;An Unconference is a gathering of people around a theme or purpose, but without a defined schedule. The schedule develops from conversations amongst the attendees, on the day. Low fees (my ticket cost £10) and a lack of sponsorship are features of an unconference, and the concept has grown out of science fiction conventions.&lt;/p&gt;
                              
                              &lt;p&gt;The introductory speeches were a slightly confused jumble of the principles of Lean development, and how they apply to making profitable software in 2010.&lt;/p&gt;
                              
                              &lt;p&gt;Next up was a piece by the CEO of Seedcamp, Reshma Sohoni.
                              Key points for me were:
                              * It is crucial to connect with your customers to make sure that you are building something that people want to buy, and that they want to buy it from you. Consultancy can really help your business to do this.
                              * Care must be taken to find a balance between customer-driven features and using your own expertise to develop features which the customer wouldn't have thought of, but that they love when they get to use it.
                              * The key difference between geek-preneurs &quot;playing with&quot; VC funding and actual successful businesses is finding and building something that people will pay for.
                              * Hire passion, not experience.
                              * Scale your team vertically.&lt;/p&gt;
                              
                              &lt;p&gt;The first proper unconference spot I went to was a session from John Williams, the author of &lt;a href=&quot;http://www.screwworkletsplay.com/&quot;&gt;&quot;Screw work, lets play&quot;&lt;/a&gt;.
                              He drew up a chart of the ideal roles he felt you should have in a creative team, using slightly outlandish titles such as:
                              * Mechanic
                              * Creator
                              * Star
                              * Supporter
                              * Deal maker
                              * Accumulator
                              * Lord
                              * Trader&lt;/p&gt;
                              
                              &lt;p&gt;The discussion centred around how these characters need each other to create a successful product, and around the process flow between them. By asking questions such as: &quot;What aspects of your work are you most enthused about?&quot; you can work out which role you really are. We talked about playing to your strengths: there's little point in trying to be a mechanic if you just aren't good at it; but also you need generalists or polymaths if you can't afford to hire more people.&lt;/p&gt;
                              
                              &lt;p&gt;One point that stuck with me was: &quot;Lords are prone to over-researching - if you have more than one Lord you move very slowly.&quot;&lt;/p&gt;
                              
                              &lt;p&gt;Moving onto the main event of the day. The &lt;a href=&quot;http://en.wikipedia.org/wiki/David_Heinemeier_Hansson&quot;&gt;dark prince&lt;/a&gt; himself: David Heinemeier Hansson.
                              DHH was basically there to pimp Rework, his recent book. I'd estimate that a good percentage of the attendees had read the book, and that almost all attendees were fully on board with Getting Real principles. Unfortunately DHH didn't bother to find this out with a quick straw poll, but instead ranted through the cartoon world of Rework, bashing out the familiar, simplistic views in a reedy, tense tone.&lt;/p&gt;
                              
                              &lt;p&gt;Particularly galling opinions were:
                              * A financial plan is nothing more than a financial wish.
                              * Plans are a waste of time - the sooner you realise that, the sooner you can forget them.
                              * Plans are worth no more than a 15 min pres, but they get much more credence than that in business.&lt;/p&gt;
                              
                              &lt;p&gt;There was also some common sense:
                              * A plan that doesn't change your behaviour is worthless.
                              * Plans promote an illusion of agreement.
                              * Decisions are temporary.
                              * You get real feedback from real software.
                              * People think they want a ton of features, but they actually buy simple solutions to clear problems.&lt;/p&gt;
                              
                              &lt;p&gt;Other points:
                              * When building Basecamp, DHH and Fried didn't want to compete with other forum providers, or CMS providers, or (shudder) Sharepoint - they only wanted to create something which is &quot;slightly better&quot; than email. Which is interesting, because I've always thought Basecamp is &quot;slightly worse&quot; than email.
                              * Making your app modular or optional will result in the quality of the user experience degrading.&lt;/p&gt;
                              
                              &lt;p&gt;There then followed a question and answer session, via skype from San Francisco with &lt;a href=&quot;http://www.startuplessonslearned.com/&quot;&gt;Eric Ries&lt;/a&gt;. Eric did a masterly job in engaging with DHH's confrontational style without being drawn into it, and provided some much needed balance to the assertion that all VC funded companies are bad.&lt;/p&gt;
                            </content>
    <published>2010-05-12T10:24:00+01:00</published>
    <updated>2010-05-12T10:24:00+01:00</updated>
    <category term='agile-software-development'></category>
    <category term='archives'></category>
  </entry>
</feed>

