Friday, December 20, 2013

The Geek Christmas Quiz 2013

This is the second year of my Geek Christmas Quiz. Six sections of the ultimate geek questions. The office competition was won by Toby Carter with a score of 46. See if you can do better.

The answers are here.

Last year’s quiz is here.

What does this acronym stand for? (one point per correct answer)
    1. AWS
    2. SQL
    3. NATO
    4. GNU
    5. SCSI
    6. HTML
    7. HTTP
    8. ReST
    9. NASA
    10. RAF

Name that computer (one point for the model, another for the company/inventor)

Quiz_name_that_computer

Name that programming language (one point for each correct answer)

1.    
10 PRINT "HELLO WORLD"
20 GOTO 10 

2.    
while(true)
{
    Console.WriteLine("Hello World");
} 

3.    
for(;;) {
    printf("Hello World");
} 

4.    
let rec hello () =
    printfn "Hello World"
    hello() 

5.    
while true
    writeln ("Hello World") 

6.    
WHILE 1 = 1 PRINT "Hello World" 

7.    
while /bin/true; do echo -n 'Hello World!'; done; 

8.    
(while true (print "hello world")) 

9.    
let hello = do putStr "Hello World"; hello 

Science fiction (one point for each correct answer)

    1. "These are not the droids you are looking for" (what film?)
    2. "Open the pod bay doors please HAL" (what film, or book?)
    3. Who wrote Rendezvous with Rama?
    4. What spaceship uses dilithium crystals
    5. what does the acronym CREW in Iain Bank's culture novels mean when referring to weapons
    6. Name 3 futurama characters
    7. Who wrote the 3 laws of robotics?
    8. What is the first law of robotics?
    9. Who is the leader of the Daleks?
    10. Directive? (which film?)

Science (one point for each correct answer)

    1. 1 degree fahrenheit is a different size to 1 degree centigrade which means they must cross at some point. At what temperature are both scales the same?
    2. When and where was the first cell in your body created?
    3. What is the device which blends air and fuel in an internal combustion engine called?
    4. What was the name of the first hydrogen (thermonuclear) bomb test?
    5. What is special about Sirius, the Dog Star?
    6. What year did the last man land on the moon?
    7. Who invented the jet engine?
    8. In trigonometry what is calculated by dividing the adjacent over the hypotenuse?
    9. Which part of the Earth lies between the outer core and the crust?
    10. Where in the body are alveoli to be found?

Name that cartoon character (one point for each correct answer)

Quiz_name_that_cartoon_character

Tuesday, December 17, 2013

How to Run a Successful Open Source Project

A couple of months ago I attended BarCamp Brighton, an open conference at Brighton University. Everyone is encouraged to present a session, and as I don’t need much excuse to talk to a room full of people I thought I’d do an unrehearsed talk on running an open source project based on my experiences with EasyNetQ. I spent about half an hour going through what EasyNetQ is, its history, and how I organise things, to a room of six people. I know, fame at last! The really interesting bit came during the questions when I got into a discussion with a chap who worked for the Mozilla foundation. He asked what makes a successful open source project. Of course ‘success’ is very subjective. Success for me means that some people are interested enough in EasyNetQ to download it from NuGet and commit time to sending me bug reports and pull requests, for other people success might be defined as a project so popular that they can make a living from supporting it. Given the former, lower bar, here are some of the things that we came up with.

  • It has to do something useful. Obvious, yes. The classic ‘scratching an itch’ reason for starting an OSS project usually means that it’s useful to you. How successful your project will be depends on how common your problem is.
  • A clear mission. If you have a clear mission, it’s easy for people to understand the problem you are trying to solve. EasyNetQ’s mission is to provide the simplest possible API for RabbitMQ on .NET. People know what the intention is, and it provides a guide to EasyNetQ’s design.
  • Easy to install. If your environment provides a package manager, make sure your project provides a package for it. Otherwise make sure you provide a simple installer and clear instructions. Don’t insist that people build your project from source if you can avoid it. EasyNetQ installs from NuGet in a few seconds.
  • A good ‘first 20 minutes’ experience. Make your project super easy to get started with. Have a quick start guide to help users get something working as soon as possible. You can get EasyNetQ up and running with two console apps publishing and subscribing within 10 minutes. Hmm, I need to get that quick start guide done though :p
  • Documentation! Clear, simple to follow, documentation is really helpful to your users. Keep it up to date. A wiki that anyone can update is ideal. I use the GitHub wiki for EasyNetQ’s documentation. If you can register a domain name and have a nice homepage with a short pithy introduction to your project, so much the better.
  • A forum for communicating with your users. I use a Google group. But there are many other options. Make sure you answer people’s questions. Be nice (see below).
  • Let people know what’s happening. A blog, like this, is an ideal place to write about the latest project news. Let people know about developments and your plans for the future.
  • Release early, release often. Long feedback loops kill software. That’s true of any project, open or closed, but much more so for open source. The sooner you get your code in front of people, the sooner you find out when it isn’t working. Have a continuous build process that allows people to be able to quickly install the very latest version. You can split out ‘stable’ from ‘development’ releases if you want. I don’t bother, every commit to EasyNetQ’s GitHub repository is immediately published to NuGet, but that will probably change as the project matures.
  • Have a versioning policy and explain it. You can see EasyNetQ’s here.
  • Use GitHub to host your source code. Yes, yes, I know there are alternatives, but GitHub has made hosting and contributing to OSS projects much easier. It has become so ubiquitous that it’s the obvious choice. Everyone knows how it works.
  • Be nice! It’s easy to get frustrated with weird questions on the mailing list, or strange pull requests, but always remember to be polite and helpful. Be especially nice to people who send you bug reports and pull requests, they are helping your project for no gain. Be thankful.

I’m sure there are loads of other things that I’ll think of as soon as I hit ‘publish’ on this post, so don’t think of this as comprehensive. I’d love to hear any more suggestions in the comments.

Of course the main problem most people have to overcome with running an OSS project is finding the time. I’ve been extraordinarily fortunate that 15below have sponsored EasyNetQ. If you use it and like it, don’t forget to thank them.

Thursday, December 12, 2013

Are Your Programmers Working Hard, Or Are They Lazy?

When people are doing a physical task, it’s easy to assess how hard they are working. You can see the physical movement, the sweat. You also see the result of their work: the brick wall rising, the hole in the ground getting bigger. Recognising and rewarding hard work is a pretty fundamental human instinct, it is one of the reasons we find endurance sports so fascinating. This instinctive appreciation of physical hard work is a problem when it comes to managing creative-technical employees. Effective knowledge workers often don’t look like they are working very hard.

Back in 2004, I was a junior developer working in a large team on a cable TV company’s billing and provisioning system. Like all large systems it was made up of a number of relatively independent components, with different individuals or small teams looking after them. The analogue TV and digital TV provisioning systems were almost entirely separate, with a different team looking after each.

The analogue TV team had decided to base their system around an early version of Microsoft Biztalk. There were four of our guys and a team from Microsoft developing it and running it in production. They all appeared to work really hard. They would often be seen working into the night and at weekends. Everyone would drop what they were doing to help with production issues, often crowding around a single guy at a desk, offering suggestions about what could be wrong, or how to fix something. There was constant activity, and anyone could see, just by looking that, not only did everyone pull together as a team, but they were all working really really hard.

The digital TV provisioning team was very different. The code had been mostly written by a single guy, let’s call him Dave. I was a junior maintenance developer on the team. Initially I had a great deal of trouble understanding the code. There wasn’t one long procedure somewhere where all the stuff happened, instead there were lots of small classes and methods with just a few lines of code. Several of my colleagues complained that Dave made things overcomplicated. But Dave took me under his wing and suggested that I read a few books on object oriented programming. He taught me about design patterns, the SOLID principles, and unit testing. Soon the code started to make sense, and the more I worked on it the more I came to appreciated its elegant design. It didn’t go wrong in production, just hummed away doing its job. It was relatively easy to make changes to the code too, so implementing new features was often quite painless. The unit tests meant that few bugs made it into production.

The result of all this was that it didn’t look like we were working very hard at all. I went home at 5.30pm, I never worked weekends, we didn’t spend hours crowded around each other’s desks throwing out guesses about what could be wrong with some failing production system. From the outside it must have looked like we’d been given a far easier task than the analogue TV guys. In truth, the requirements were very similar, we just had better designed and implemented software, and better supporting infrastructure, especially the unit tests.

Management announced that they were going to give out pay rises based on performance. When it was my turn to talk to the boss, he explained that it was only fair that the pay increases went to the people who worked really hard, and that our team just didn’t seem to care so much about the company, not compared to the heroes who gave up their evenings and weekends.

The cable company was a rare laboratory, you could observe a direct comparison between the effects of good and bad software design and team behaviour. Most organisations don’t provide such a comparison. It’s very hard to tell if that guy sweating away, working late nights and weekends, constantly fire-fighting, is showing great commitment to making a really really complex system work, or is just failing. Unless you can afford to have two or more competing teams solving the same problem, and c’mon, who would do that, you will never know. Conversely, what about the guy sitting in the corner who works 9 to 5, and seems to spend a lot of time reading the internet? Is he just very proficient at writing stable reliable code, or is his job just easier than everyone else’s? To the casual observer, the first chap is working really hard, the second one isn’t. Hard work is good, laziness is bad, surely?

I would submit that the appearance of hard work is often an indication of failure. Software development often isn’t done well in a pressurised, interrupt driven, environment. It’s often not a good idea to work long hours. Sometimes the best way of solving a difficult problem is to stop thinking about it, go for a walk, or even better, get a good night’s sleep and let your subconscious solve it. One of my favourite books is A Mathematician’s Apology by G. H. Hardy, one of the leading British mathematicians of the 20th century. In it he describes his daily routine: four hours work in the morning followed by an afternoon of watching cricket. He says that it’s pointless and unproductive to do hard mental work for more than four hours a day.

To managers I would say, judge people by results, by working software, not by how hard they appear to be working. Counter intuitively, it may be better not to sit with your developers, you may get a better idea of their output unaffected by conventional/intuitive indicators. Remote working is especially beneficial; you will have to measure your employees by their output, rather than the lazier option of watching them sitting at their desks 8 hours a day thumping away at an IDE, or ‘helpfully’ crowding around each other’s desks offering ‘useful’ suggestions.

Monday, December 09, 2013

EasyNetQ: Replace the Internal DI Container

logo_design_150

EasyNetQ, is made up of a collection of independent components. Internally it uses a tiny internal DI (IoC) container called DefaultServiceProvider. If you look at the code for the static RabbitHutch class that you use to create instances of the core IBus interface, you will see that it simply creates a new DefaultServiceProvider, registers all of EasyNetQ’s components, and then calls container.Resolve<IBus>() creating a new instance of IBus with its tree of dependencies supplied by the container:

public static IBus CreateBus(IConnectionConfiguration connectionConfiguration, Action<IServiceRegister> registerServices)
{
Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration");
Preconditions.CheckNotNull(registerServices, "registerServices");

var container = createContainerInternal();
if (container == null)
{
throw new EasyNetQException("Could not create container. " +
"Have you called SetContainerFactory(...) with a function that returns null?");
}

registerServices(container);
container.Register(_ => connectionConfiguration);
ComponentRegistration.RegisterServices(container);

return container.Resolve<IBus>();
}

But what if you want EasyNetQ to use your container of choice? From version 0.25 the RabbitHutch class provides a static method, SetContainerFactory, that allows you to register an alternative container factory method that provides whatever implementation of EasyNetQ.IContainer that you care to supply.

In this example we are using the Castle Windsor IoC container:

// register our alternative container factory
RabbitHutch.SetContainerFactory(() =>
{
// create an instance of Windsor
var windsorContainer = new WindsorContainer();
// wrap it in our implementation of EasyNetQ.IContainer
return new WindsorContainerWrapper(windsorContainer);
});
// now we can create an IBus instance, but it's resolved from
// windsor, rather than EasyNetQ's default service provider.
var bus = RabbitHutch.CreateBus("host=localhost");

Here is how I implemented WindsorContainerWrapper:

public class WindsorContainerWrapper : IContainer, IDisposable
{
private readonly IWindsorContainer windsorContainer;

public WindsorContainerWrapper(IWindsorContainer windsorContainer)
{
this.windsorContainer = windsorContainer;
}

public TService Resolve<TService>() where TService : class
{
return windsorContainer.Resolve<TService>();
}

public IServiceRegister Register<TService>(System.Func<IServiceProvider, TService> serviceCreator)
where TService : class
{
windsorContainer.Register(
Component.For<TService>().UsingFactoryMethod(() => serviceCreator(this)).LifeStyle.Singleton
);
return this;
}

public IServiceRegister Register<TService, TImplementation>()
where TService : class
where TImplementation : class, TService
{
windsorContainer.Register(
Component.For<TService>().ImplementedBy<TImplementation>().LifeStyle.Singleton
);
return this;
}

public void Dispose()
{
windsorContainer.Dispose();
}
}

Note that all EasyNetQ services should be registered as singletons.

It’s important that you dispose of Windsor correctly. EasyNetQ doesn’t provide a Dispose method on IContainer, but you can access the container via the advanced bus (yes, this is new too), and dispose of windsor that way:

((WindsorContainerWrapper)bus.Advanced.Container).Dispose();
bus.Dispose();

Happy containerisation!