codelord.net

Code, Angular, iOS and more by Aviv Ben-Yosef

How I Moved My WordPress Blog from Dreamhost to a Free EC2 Instance

| Comments

Just recently my Dreamhost plan, the one this blog is hosted on, expired and I had to renew it. Seeing the amount of money they took charge me realize that surely I can find something cheaper than >$10/month. After some snooping around I’ve settled on moving my WordPress blog to EC2. This is my story.

Disclaimer: this worked for me. If you lose your blog, too bad. Backup is your friend, my friend. You need some devops-chops to follow along.

After being tipped of by a couple of friends, I decided to look into setting up my site on EC2. Basically, my blog is really small (the WordPress export file is about 2MB), and it’s not like I get tons of traffic. That alone means that for a year now I can use the EC2 free tier, making this blog cost pretty much nothing.

Initial setup

First step was to register and AWS account. I created a micro instance, which is enough for most blogs and free for a year. The AMI (image) of the instance I used was Bitnami’s prebundled WordPress image, which you can read more about here. Do make sure to create your instance on an EBS and not instance store. That means that the data will be persistent. Change the instance’s security group to allow connections to port 80 (HTTP) and port 22 (SSH) from any IP.

You can assign a static IP to your instance for free! Just allocate a new Elastic IP on the EC2 console and attach it to your instance. Note that Elastic IPs cost nothing while attached, by if they aren’t attached your bill will start growing (after all, fresh IPs are a rare resource).

So you’ve got your instance up, eh? You can point your browser to your instance’s public DNS name, like so http://ec2-something-something.com/wordpress and see the default WordPress hello page. Go to /wordpress/wp-admin to login as admin (the default bitnami user/password are user/bitnami). Here you can start and setup your blog again.

Importing

On your original blog, you can use the export utility and then import all your posts and comments to the new machine. Easy as pie. If you have a lot of plugins and configurations, you might want to search for one of the many plugins that do that for you. If you’re like me and only have a couple of plugins and one theme, installing them manually takes about 3 minutes.

Moving WordPress to the root of the site

If you’d like to move WordPress to the root of your site (/ instead of /wordpress), remove the path from the General settings page and then SSH to the machine. Replace the first two lines of the file /opt/bitnami/apps/wordpress/conf/wordpress.conf with:

1
Alias / "/opt/bitnami/apps/wordpress/htdocs/"

Then, go to /opt/bitnami/apache2 and do:

1
sudo ./bin/apachectl restart

Gotchas

Got permalinks? You’ll need to:

1
chmod g+rw /opt/bitnami/apps/wordpress/htdocs/.htaccess

Want to receive email notification for new comments etc.? You’ll need to do:

1
sudo apt-get install sendmail && sudo ln -s /usr/sbin/sendmail /usr/bin/sendmail

If you have attachments in any of your posts, you might need to fix the URL after the final move.

Testing

Make sure all your links, widgets etc. are working before making the final move. Post something, add a comment.

Going live

In the General settings panel, change the URL of the blog to your domain. Go to wherever you were hosted before, find the DNS panel and change the DNS entries for your blog. Danger: This is an “expert” step, and if you don’t know what it means, I recommend grabbing someone with more knowledge. Change the A records for your domain to point at the elastic IP you gave your instance. That’s it! Wait a bit for DNS propagation and everything should be working!

Backups

I found out about the backup to dropbox plugin, which simply uploads all your blog to dropbox! Sweet, awesome and easy for small blogs!

Costs

So, using 1 micro instance with an EBS store of 10GB is free for the first year. Given nothing crazy in terms of network, you shouldn’t be paying at all for the first year, maybe about $1 a month. After that year passes, the instace and EBS store start kicking in. If you’re in it for the long run, like me, paying for the instance a year in advance costs about $9/month (3 years is like $7), and the EBS store costs $0.1 per GB, meaning $1. That’s about $10-$8/month, depending on how you pay for the instance. A great save compared to Dreamhost!

You should susbcribe to my feed and follow me on twitter!

Stop Bitching: Write Those Damn Tests

| Comments

Diving deeper into the idea of the Autonomous Craftsmanship Core, this time I’d like to talk about one of the first problems a lot of developers face when wanting to start doing clean code.

You read Uncle Bob’s Clean Code, or went to a talk and then go all “Next day at work I’m gonna write tests!!” Then you come to work, and you give the “let’s write tests man!” speech to your teammate, and he just yawns, and slowly the rush fades.

Lots have been written before about introducing tests to a team as a grunt, but I’ll do a quick recap:

You don’t have to ask anyone in order to start and write some tests. Write that first test. Make it pass. Commit. Not that hard, isn’t it?

Usually the next problem is that if no one else on your team runs the tests, they will keep breaking. But can you blame your team? You need to make them understand that running the tests will actually get them something.

For example, I’ve seen that after someone makes a commit that breaks the tests because of a bug, coming over to him and telling him what went wrong and how you found out might make him more interested in the idea of testing. A friend recently told me that he made running tests as simple as a double-click for the developers that don’t write tests. Once it got that easy, they started running them because everyone likes knowing that what they wrote works.

What if your boss won’t let you write tests? Frankly, why the fuck should your boss care? Does he also tell you when to use “while” instead of “for”? I don’t find things such as these to be something any boss should decide about. As I’ve said in the first post, if you find yourself in a place so resistant to change, leave. If you have to stay, do what you have to do. If they won’t let you commit your tests to source control or set up a continuous integration machine, there are solutions, which I’ll discuss on my next post.

In the mean time, focus on writing tests that help your teammates find problems and see how slowly your little tests get more and more traction. It’ll work, because Success begets attention!

You should subscribe to my feed and follow me on twitter!

Stop Bitching: the Autonomous Craftsmanship Core

| Comments

A lot of developers I know keep bitching about how their team isn’t as passionate as they’d like it to be, or about their boss not letting them do things like it should be done. They get into this habit and never advance in the right direction because something is holding them back. I know this situation well, I’m usually one of these guys.

In the spirit of Positivember I’d like to tell you a secret. You can stop whining and start improving. You don’t have to wait for all the stars to align. That cliché about changes starting from yourself is actually right.

I’ve heard almost every complaint in the book:

“My teammates don’t write tests.” “They won’t let me have a continuous integration server.” “I can’t use Git.” “My boss hates it when I make a lot of commits.” “I was told not to write tests.” “We’re not doing agile development.” “I can’t do pair programming.”

If everything above applies, or you really have lots of problems like these, just quit. A developer that really cares about these things usually can find a better job easily. But, if it’s only some of these, remember that no work is perfect. There will always be suboptimal stuff to live with. The trick is not to be all bitter about it, but to actually try and make changes happen, slowly, so you still have fun.

Most if not all of these problems are things you can work around, technologically, mentally or socially. If you just stick to your good ways, you’ll eventually get some followers too.

Step up and realize that everything can start by you and your habits. An Autonomous Craftsmanship Core as I like to call it. Sometimes, you core will seem so awesome from the outside that people will join in on some of your practices. Sometimes it will go unnoticed and you will happily go on programming better and better.

I will blog more on tackling some of the problems I mentioned above, but as a starting point I recommend Apprenticeship Patterns and Driving Technical Change. These great books help a lot in accepting that fact you should take matters into your own hands, and stop bitching.

You should subscribe to my feed and follow me on twitter!

Stepping Up: Do the Pre-Commit Skim

| Comments

I’m always looking for the easiest way to make my code better, or to train myself to pay more attention to the quality of the code I produce. My latest find is quite obvious yet so very powerful I had to share. Simply put, it’s just going over your code once more before a commit.

Every once in a while, I commit code and forget to add a file. Even worse, I sometimes leave around dead code that I really hate. I’ve found out that simply making a mental note to go over every file I changed before making a commit makes a big difference. It seems like the Boy Scout Rule from Clean Code is a special case of this rule.

The trick is to simply go over every file you’ve changed and look for common pitfalls:

Unused code – Are there methods your changes just made obsolete? Maybe a conditional with an “else” clause that can no longer happen? Delete code! It’s the best code you’ll write today!

Zombie code – Did you start with something that was too complex and is no longer needed? Often in retrospect you can see how to simplify something and spare your colleagues the woes of zombie code.

Overdue refactoring – Look at your changes. Are you pushing a method too far? Maybe making a class too bloated? Maybe it’s time to for some cleaning.

Do you have a better name for it now? Sometimes when you start with something you don’t have a great name for it. After finishing it, you might be able to slap a better name on that class that will make it more obvious to everyone.

Any dangling TODOs? I hate committing TODOs unintentionally.

Make sure it’s all coherent in class-level – Some changes make sense when you’re knee-deep in a change. But step back and make sure it all still makes sense.

You should subscribe to my feed and follow me on twitter!

Fight Zombie Code

| Comments

If there’s anything I hate more than dead code, it’s zombie code. Dead code is code that’s remained in the system even though it’s no longer really used.

It might be small, like unused imports, instance variables and methods. It can be whole classes that make up entire features no longer used.

The biggest PITA is when you’re not really aware of the fact the code’s dead and unused, sitting there and occupying precious bits, and stumble across it as part of a task, trying to understand how it influences what you want to do next.

Whenever I recognized something that looks like dead code but I’m not entirely sure, I find it pretty easy to delete it quickly, once I take a look in the version control logs and see when it became no longer in use and why.

Zombie code is code that was never alive, and so couldn’t really become dead. It’s the undead code – code that died right when it was committed. Code that never ran or never worked. The are two reasons I hate zombie code more than “plain” dead code.

The first reason is that it simply wastes more of my time. Looking back in version control won’t help me see the commit in which the code was “decommissioned”, it would just appear to always sit there. That means I have to take extra care to verify that it, in fact, never worked.

The second reason is that it’s plainly someone saying he doesn’t give a damn. I mean, let’s put aside TDD. Heck, let’s put aside unit testing at all. It means the code never even ran the damn thing and saw in his own eyes it did what he claims it did.

Be kind to your teammates. If you’re not a good enough coder to test it, at least see that it runs once in your own eyes.

You should subscribe to my feed and follow me on twitter!

TIL: Ruby Classes that Look Callable

| Comments

One of the concept I had to get used to moving from Python to Ruby was that regular objects aren’t callable, and that there was a closed set of objects that can be called. Meaning that where in Python it was possible for any class to implement call and so allow us to call it with obj(), Ruby doesn’t allow this. One of the advantages of that syntax in Python is that each class implements its constructor using this. For example:

This was a nice little trick I liked in Python but quickly got used to living without it. That was until I saw Ruby code that seemed to allow the exact same behavior:

How’s this so? Can we really make classes callable? A quick glance at Integer’s source code in the Rubinius code reveals that there’s no magic going on in it, and that it actually has no reference for this method I’m looking to call. Instead what we’ll see is that alongside the class definition there’s also a method definition:

So the whole trick is simply to define both. But how exactly does this work? How are names not clashing?

What actually happens is that whenever we define a new class or module, its name is added as a constant that points to the actual class. Similarly, when we define a method at the top level it’s added as a private method to Object. That means that whenever we type in a name that looks like a constant (starts with a capital letter) without parenthesis, Ruby will search for that constant:

But when we add parenthesis, Ruby understands that it should seek for a method instead:

This nifty little trick is all it takes for Ruby to allow this nice syntax.

Hope you learned a new thing! In case you want to dig deeper, two great books that really helped me wrap my head around dark corners of Ruby are Eloquent Ruby and Metaprogramming Ruby.

You should subscribe to my feed and follow me on twitter!

Submitting your first patch to Rubinius

| Comments

I always love helping interesting open source projects, and Rubinius is one of those great projects that are very cool to play with. In case you don’t know it, Rubinius is a Ruby implementation written (almost) entirely in Ruby. Just playing with such a code base is quite interesting and whenever a peek around in the code I learn new stuff about Ruby.

At the moment, the people at Rubinius are working hard on making it compatible with ruby 1.9, and so there are a lot of easy changes that are waiting for you to do and start contributing. I’d like to show you a quick walk-through of how to find such simple tasks and get started.

Setup

Clone the project from the GitHub repo. Once that’s done, to make sure that everything works properly do this:

1
2
./configure
rake spec

The specs should be all passing on your machine. It will take a few minutes the first time, but afterwards whenever you make small changes it will be faster.

Finding interesting work

Of course you can submit whatever patch you find interesting, but in my opinion a quick way to get started is to find incompatibilities with 1.9. Fortunately for you, it’s pretty easy to find those.

Rubinius, along with the other Ruby implementations, uses mspec in order to have written specs of the language written in Ruby and is checked against that. These specs are similar to RSpec. Among other options, some specs are simply marked as having to pass only on Ruby 1.9 and of these, those that are currently failing are our hunt.

I came up with this command in order to find and execute such 1.9 specs that were last reported by Rubinius developers to be failing:

1
bin/mspec tag --list fails -tx19 :ci_files

This command will list the RubySpecs that are tagged as failing on Rubinius in 1.9 mode.

You should see plenty (at the time of this writing, over 500) of failing specs. Just pick something that seems easy enough to get started with.

Once you spot a spec that looks interesting you can run it specifically and see the code. For example, if you see an interesting spec for String#squeeze, you can run it with:

1
bin/mspec -tx19 spec/ruby/core/string/squeeze_spec.rb

Doing some work

For example, let’s look at one of the really simple specs I decided to get passing, you can see the commit here. I wanted to make a simple change to the String#ord method, but only on 1.9 version. The way to do that on Rubinius is that many of the files, say string.rb now have also “string18.rb” and “string19.rb” that contain the code that differs. In my case, I just made a simple change to the version used on 1.9 by editing the ord method on the string19.rb file (in case the 19 and 18 files don’t exist yet, you can simply create them like shown here).

After you’ve made your changes, be sure to run the specs again and see that everything works. Before submitting it, you should make sure to run all specs thoroughly using the command rake spec. If all is well, just do the regular GitHub pull-request dance and off you go!

Further than that, you can include in your pull request another commit that removes the failing tags from the specs you’ve just fixed. Find the appropriate file and just remove it, as you can see in this commit.

For some more in depth review of how to start contributing to Rubinius, see this excellent post on the official blog.

You should subscribe to my feed and follow me on twitter!

When being idiomatic wears you out

| Comments

I believe that when learning a new programming language, it’s really important to learn its idioms and use them. I’ve written procedural C-like code in Java, and bloated Java-like code in Python, but only once you start using a language “like it was meant to” can you really say you’ve started mastering it. Had I not read Effective Java I don’t think I could have ever written a sensible line in this language.

I practically cringe whenever I see someone creating a new list in Java and then adding to it a single element when he just could have used Collections.singletonList(element). I’m that kind of a fanatic.

But, lately I’m getting worn out of being verbose. Yes, you can use the trick above to save a line of code and a lot of typing, but damn it – I just want to say [element]!

Less than a month into BillGuard we realized we don’t want to do all of our coding in Java and started calling Python code from Java (not in the JVM though, since Jython just doesn’t seem solid enough). Running away from Java’s notoriously long idioms, we preferred adding the overhead of having multiple programming languages in one project (which I think justified itself plenty, but it is an overhead).

This solution helped us when doing big stuff we didn’t want to do in Java, stuff that we’d represent in a unique class. But the smaller stuff just kept nagging us. We kept finding ourselves writing 10-15 lines of code to do something we thought trivial and then putting a 1-2 lines of comments before it saying what we actually meant in Python. These eventually lead to a lot of extracted methods which are generally good, but rarely would I extract such logic in Python/Ruby – where it would be a single concise line of code.

Lately, we started toying with just saying “screw the idioms” and doing what feels right. If that means having a JavaSucksUtils class with methods such as zip() and defaultdict_int() so be it. I think that with time this will lead to using a wholly different language in the JVM mostly, but in the mean time this seems to be a nice transition.

I mean, common:

Now we’ll have to wait and see where this gets us.

You should subscribe to my feed and follow me on twitter!

Guest Post: Lookup Tables with Ruby-on-Rails

| Comments

This is a guest-post by Nimrod Priell (@nimrodpriell) about the kind of time-saving tricks that I’m amazed are so easy to pull off in Rails

If you want to have an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity ‘type’-like objects, read along. Or in plain English – if you want to have a table containing, say, ProductTypes which can grow with new types simply when you refer to them, and not keep the Product table containing a thousand repeating ‘type=“book”’ entries – and gain some insight into ruby metaprogramming techniques – sit down and try to follow through.

A normalized DB means that you want to keep types as separate tables, with foreign keys pointing from your main entity to its type. For instance, instead of:

ID  car_name        car_type
1   Chevrolet Aveo  Compact
2   Ford Fiesta     Compact
3   BMW Z-5         Sports

You want to have two tables:

ID  car_name        car_type_id
1   Chevrolet Aveo  1
2   Ford Fiesta     1
3   BMW Z-5         2

And

car_type_id car_type_name
1           Compact
2           Sports

The pros/cons of a normalized DB can be discussed elsewhere. I’d just point out a denormalized solution is most useful in settings like column oriented DBMSes. For the rest of us folks using standard databases, we usually want to use lookups.

The usual way to do this with ruby on rails is:

  • Generate a CarType model using rails generate model CarType name:string
  • Link between CarType and Car tables using belongs_to and has_many

Then to work with this you can transparently read the car type:

1
2
car = Car.first
car.car_type.name # returns "Compact"

Ruby does an awesome job of caching the results for you, so that you’ll probably not hit the DB every time you get the same car type from different car objects.

You can even make this shorter, by defining a delegate to car_type_name from CarType:

1
2
# car_type_name.rb
delegate :name, :to => :car, :prefix => true`

And now you can access this as

1
2
# car_type.rb
car.car_type_name

However, it’s less pleasant to insert with this technique:

1
2
3
4
car.car_type.car_type_name = "Sports"
car.car_type.save!
#Now let's see what happened to the OTHER compact car
Car.all.second.car_type_name #Oops, returns "Sports"

Right, what are we doing? We should’ve used

1
car.update_attributes(car_type: CarType.find_or_create_by_name(name: "Sports"))

Okay. Probably want to shove that into its own method rather than have this repeated in the code several times. But you also need a helper method for creating cars that way…

Furthermore, ruby is good about caching, but it caches by the exact query used, and the cache expires after the controller action ends. You can configure more advanced caches, perhaps.

The thing is all this can get tedious if you use a normalized structure where you have 15 entities and each has at least one ‘type-like’ field. That’s a whole lot of dangling Type objects. What you really want is an interface like this:

1
2
3
4
car = Car.first
car.car_type #returns "Compact"
car.car_type = "Sports" #No effect on Car.all.second, just automatically use the second constant
car.car_type = "Sedan" #Magically create a new type

Oh, and it’ll be nice if all of this is cached and you can define car types as constants (or symbols). You obviously still want to be able to run:

1
CarType.where(:id > 3) #Just an example of supposed "arbitrary" SQL involving a real live CarType class

But you wanna minimize generating these numerous type classes. If you’re like me, you don’t even want to see them lying around in app/model. Who cares about them? I’ve looked thoroughly for a nice rails solution to this, but after failing to find one, I created my own rails metaprogramming hook. The result of this hook is that you get the exact syntax described above, with only two lines of code (no extra classes or anything):

In your ActiveRecord object simply add

1
2
3
4
5
6
7
8
# car.rb
require 'active_record/lookup'
class Car < ActiveRecord::Base
  #...
  include ActiveRecord::Lookup
  lookup :car_type, :as => :type
  #…
end

That’s it. the generated CarType class (which you won’t see as a car_type.rb file, obviously, as it is generated in real-time), contains some nice methods to look into the cache as well: So you can call

1
2
CarType.id_for "Sports" #Returns 2
CarType.name_for 1 #Returns "Compact"

and you can still hack at the underlying ID for an object, if you need to:

1
2
3
4
5
6
car = Car.first
car.car_type = "Sports"
car.car_type_id #Returns 2
car.car_type_id = 1
car.car_type #Returns "Compact"
car.find_car_by_type_and_color("Compact", :blue) #Works, the underlying search is done by the ID

The full source code and gem can be found in https://github.com/Nimster/RailsLookup. The gem is named rails_lookup so you can just gem install rails_lookup to get the functionality required.

Note you do need to create tables for the new Type classes. The table format is very simple:

1
2
3
4
create_table :car_types do |t|
t.string :name
end
add_column :cars, :type, :integer

In this post, however, I would like to elucidate how this is achieved, hopefully teaching some ruby meta-programming and rails considerations on the way.

So how do we achieve that? Well, we start with creating our own Lookup module which can be included into active record classes:

This is the basic setup for inserting a new “macro” like belongs_to (which is actually a simple class method). When the Lookup module is included in a class, the ruby interpreter will call the hook method “self.included” with the class this was included into. We ask to also extend this class, thereby adding any class methods defined in ClassMethods into it.

We can now call “lookup :car_type, :as => :type” in our Car class, only that it doesn’t do anything. Let’s make it do something. We need to achieve the following things:

  1. Create the CarType ActiveRecord
  2. Link the CarType and Car ActiveRecords (with the standard has_many, belongs_to link)
  3. Make the Car#car_type=, Car#car_type methods behave in the way we described above.
  4. (Optional) code-fill the caches when the class loads from the data in the DB

We will now present the code for each – when you read through, remember this all runs in the host class context (e.g. Car) so that self is the Car class, and any actions we take are equivalent to having explicitly written them in the Car class itself.

The important parts to note here are:

  • How we define a new class and then bind it to the constant “CarType” so that after a class containing the lookup (like Car) is referred to (just calling Car.to_s is enough), the CarType is not accessible as if it were inside of a car_type.rb file in our app/models directory.
  • How we use Rails’ built-in Inflections module which it mixes in to string, to move from so-called “table_notation” to CamelNotation and vice versa.
  • How we use class_variable_get and class_variable_set to access the class variables of the newly created CarType class – because confusingly enough @@var will refer to the class we’re in now and not the one being defined inside the block, when the code is executed. We discuss initialization of these two variables later on, during part (4).

Side note: This is not the complete class definition - I shortened it a bit to remove details which are handled in the gem version, like supporting Rails’ where() methods, support anonymous classes that have lookups and supporting multiple classes using the same lookup. If you’re interested in these, I urge you to check out the gem.

Note also that we have already included the has_many link inside of CarType. In the same way, we will include the belongs_to in the other direction. We do this and also define the special accessors for getting and setting the CarType as a String:

The important thing to note here is how we employ ActiveRecord’s read_attribute and write_attribute. The data in your ActiveRecord is maintained in a hash called attributes where the names of fields (in the DB) are saved along with their values. A classic setter method like car.car_type = "Compact" would set an attribute entry in the hash with :car_type => “Compact”, which will later cause SELECT or INSERT statements to try and access the in existing column car_type. Our approach is to intercept every time the ‘type’ attribute is being written (with a String), and replace that String with a numerical ID (meanwhile creating the corresponding CarType entry if necessary).

Finally, prefill the caches from the DB when this class loads. This is optional but as the list of types is likely to be rather small, a real-time expanding cache is just wasting some user time and could be better done ahead.

That’s it. If you don’t like the caching this becomes even easier – remove all of the references to @@rcaches and @@caches and you simply saved yourself the trouble of manually maintaining CarType objects.

The only remaining thing is to define your migrations for creating the actual database tables. After all, that’s something you only want to do once and not every time this class loads, so this isn’t the place for it. However, it’s easy enough to create your own scaffolds so that a command like

rails generate migration create_car_type_lookup_for_car

will automatically create the migration. This is the required migration

I’ll let you work out the details for actually migrating the data yourself – this post has already ran long enough. I urge you to read more in the gem’s source code here. There are some tricks I’ve omitted to make rails be able to support calls like Car.find_by_car_type_and_color “Compact”, :blue (when the actual SQL query should be asking about car_type_id = 1), and some more options for setting the lookup itself, handling Car.where(type: “Compact”) or multiple classes using a single lookup.

I hope this helped you and saved a lot of time and frustration. I’d like to thank Aviv for hosting me here. If you don’t already, read the rest of his blog, you’re sure to learn something useful! Follow me on twitter: @nimrodpriell

Today I Got Burnt by Isolated Tests

| Comments

Generally, I prefer the GOOS school of TDD which includes isolating my classes as much as possible, putting mocks and stubs everywhere. Even though one of its known disadvantages is that you risk testing your classes in a fake environment that won’t match the real production code using it, I’ve rarely come across a place where I got really bitten by it.

Today I set out with my pair to add some functionality to a certain class. That class had about 30-40 lines of code and about 10 test cases, which seemed quite decent. We added our changes TDD style and just couldn’t get the thing working. After digging into it for a few more minutes we suddenly realized the class shouldn’t be working at all and checking in the DB showed that indeed the last time that specific feature had any effect was 3 months ago!

Fortunately for us, all the problems that caused this bug are solved problems, we just need to get better at implementing the solutions:

Isolated tests go much better hand in hand with a few integration tests (some might say the right term is acceptance tests) that execute the whole system and make sure the features are working. Had we had those, we would have caught the bug much sooner.

The bug was introduced in a huge commit that changes 35 files and 1500 lines of code. We usually try and go over every commit made, even if it was paired, because we believe in collective code ownership, but it’s impossible to go over such a huge diff and find these intricacies. Working in small baby steps makes it far less likely to break something and more likely that someone else will spot your mistakes. Huge refactorings give me the creeps.

After the change was committed, it was not followed-through: this specific feature is a feature you usually notice over a few days and we missed out on making sure it kept working. We moved on to other tasks and forgot all about it, thinking it was working all this time. Had we taken the time to make sure we were seeing, it would have been squashed by the next deployment.

Any of these would have helped us spot sooner that the isolated tests were actually testing the code against a scenario that never happens. These tiny changes of our workflow would have made several of our users happier over this timeframe.

Hopefully all is well now and the feature is back at 100%, but only time will tell whether we were able to learn from this mishap.

You should subscribe to my feed and follow me on twitter!