Monday, March 10, 2014

Leave the construction to builder!

Why do we need builders? Lets say we have a class Pizza

public Pizza {
  private String flour;
  private String type;
  private String topping;
  private String seasoning;
}

Let's say the topping and seasoning are optional. You are a merciless person if you have constructors like these to construct a Pizza.

public Pizza(String flour, String type, String topping, String seasoning) {
}

public Pizza(String flour, String type, String topping) {
}

public Pizza(String flour, String type, String seasoning) {
}

public Pizza(String flour, String type) {
}
I would end up constructing an "Oregono pizza topped with wheat flour with a tomato seasoning". This might be the worst pizza you could ever have.

A builder would've been handy here. The top reasons we should go for a builder are,
  • Ambiguous class construction. Similar typed fields in Pizza class make its construction ambiguous for the clients.
  • If you want to avoid setters and make your objects thread safe especially when there are mandatory and optional fields in your class.
  • Too many fields and you don't want to make your constructor look like a cargo train.
Let's rewrite the Pizza class with a builder.

public class Pizza {
  private final String flour;
  private final String type;
  private final String topping;
  private final String seasoning;

  private Pizza(PizzaBuilder builder) {
    ValidateNotNull(builder.flour); 
    ValidateNotNull(builder.type);
    this.flour = builder.flour;
    this.type = builder.type;
    this.topping = builder.topping;
    this.seasoning = builder.seasoning;
  }
  
  // have getters for fields

  pubic static PizzaBuilder getPizzaBuilder() {
     return new PizzaBuilder();
  }

  private class PizzaBuilder {
    private String flour;
    private String type;
    private String topping;
    private String seasoning;
    
    public void withFlour(String flour) {
 this.flour = flour;
        return this;
    }
    public PizzaBuilder withType(String type) {
 this.type = type; 
        return this;
    }
    public PizzaBuilder withTopping(String topping) {
 this.topping = topping;
        return this;
    }
    public PizzaBuilder withSeasoning(String seasoning) {
 this.seasoning = seasoning;
        return this;
    }

    public Pizza build() {
        return new Pizza(this);
    }
  } 
}
Now the clients can construct a pizza like,

Pizza myFavoritePizza = Pizza.getPizzaBuilder().withFlour("Wheat").withType("Cheese").withSeasoning("Oregano").build();
This looks way better than our first approach. Isn't it? No other thread can mess with myFavoritePizza :)

~Surya

Saturday, September 28, 2013

Paginate and Play Safe

Let's write a  simple application 'LicenseDB' that exposes an API to list the vehicle numbers in the United States.

public void printNumbers() {
    LicenseDB db = new LicenseDB();
    //print db.getVehicleNumbers();
}

Congratulations! We've just blown up someone's browser or mobile or a tablet or the caller is timed out before getting a response from us. Whenever we have to expose a list API, we should be careful about the amount of data we would end up dumping. We can get around this issue by paginating our result set.

How do we paginate ?
Lets rewrite our LicenseDB API so that when a client calls getVehicleNumbers(), it returns a continuation token along with a small list of numbers.

What is a continuation token ?
From a client's perspective, a continuation token is a unique identifier returned by getVehicleNumbers() which when passed to getVehicleNumbers() on a subsequent call, will return the next set of vehicle numbers.

In getVehicleNumbers() implementation, a continuation token is a bookmark that identifies the next list of vehicle numbers that gets returned to the caller. Let's give it a shot.

class ResultSet {
    private final List <String> results;
    private final String continuationToken;

    public ResultSet(List<String> results, String continuationToken) {
        this.results = result;
        this.continuationToken = continuationToken;
    }

    public List <String> getResults() {
        return results;
    }

    public String getContinuationToken() {
        return continuationToken;
    }
}

class LicenseDB {
    public ResultSet getVehicleNumbers(String continuationToken) {
        // parse the continuationToken to get the bookmark info.
        List <String> result = db.retrieve(bookmark);
        // construct a new continuation token. If there are no more results, return a null.
        String continuationToken = constructNewContinuationToken();
        return new ResultSet(result, continuationToken);
    }
}
A naive client side code would do something like,

public void printNumbers() {
    String continuationToken = null;
    do {
        ResultSet result =  db.getVehicleNumbers(continuationToken);
        continuationToken = result.getContinuationToken();
        // print result.getResults();
        // break if user doesn't want more results.
    } while (continuationToken != null);
}
We can also add the size of the result set along with continuation token on calls to getVehicleNumbers(), so that clients can control the size of the result they get every time.

What have we done ?
If we have to expose a list API without pagination as a web service, preparing the whole list in one HTTP request on our end is a bad customer experience. Often they will time out or their browser will run out of memory once we dump the response.

By returning a paginated result, we have given the control over to the clients to decide what they want from our API.

~Surya.

Tuesday, September 10, 2013

Retry and Recover

Coding against eventually consistent systems

Eventual consistency is a key concept in most distributed systems. Lets consider a distributed storage system, we can say it is eventually consistent if the data that we write/update will eventually be available to all the users at some point if not immediately. When we write an application that depends on such a system, our application shouldn't suck at intermediate failures and should be able to quickly recover from transient issues. Amazon S3 is a good candidate for a storage service that is eventually consistent. So lets write a very simple piece of code which,

1. Creates a bucket in Amazon S3
2. Adds an item to the bucket

If we write something like the following, we are in deep trouble.

AmazonS3 s3 = new AmazonS3Client(awsCredentials);
String bucket = "awesome_bucket";
s3.createBucket(bucket);
s3.putObject(bucket, "my_key", file);

The call to createBucket() doesn't guarentee the availability of bucket immediately. As a result,
s3.putObject() may fail with a BucketNotFoundException and that's bad.

A better code would be,

AmazonS3 s3 = new AmazonS3Client(awsCredentials);
String bucket = "awesome_bucket";
boolean bucketExists = false;
int tries = 0;
while (tries < MAX_RETRIES) {
    tries++;
    s3.createBucket(bucket);
    if ((bucketExists = s3.doesBucketExist(bucket))) {
        break;
    }
    Thread.sleep(1000);
}
if (bucketExists) {
    s3.putObject(bucket, "my_key", file);
}

Let's go one step further and come up with a nice abstraction. A functor could've made things much simpler. Anyways,

public void eventually(Runnable retryableTask, 
        Callable<Boolean> validatorTask,
        long bailOutTimeInMs) throws Exception {

    int noOpInMs = 1000;
    Exception retryableTaskException;
    while (bailOutTimeInMs > 0) {
        try {
            retryableTask.run();
        } catch (RuntimeException e) {
            retryableTaskException = e;
        }
        if (taskValidator.call()) {
            return;
        }
        Thread.sleep(noOpInMs);
        bailOutTimeInMs -= noOpInMs;
        noOpInMs *= 1.2;
    }
    throw retryableTaskException;
}
Basically the above wrapper takes in a retryable task and a validator task and sleeps between two tries with a geometric back off timer. If validator task returns success, then we return.

Lets try our example using the wrapper,

eventually(
    new Runnable() {
        @Override
        public void run() {
            s3.createBucket(bucket);
        }
    },
    new Callable() {
        @Override
        public Boolean call() {
            return s3.doesBucketExist(bucket);
        }
    });

This way, we can submit any task that needs to be retried conditionally. If we want to make the validator return an object, we can use generics and pass a Callable <T> validatorTask.

What have we done ?
  • We made sure that our service is resilient to intermittent inconsistencies caused by dependent services that are eventually consistent.
  • Written a template to which we can submit retry-validate logic so that we don't end up writing while loops and conditional breaks all over our business logic and trash the code.
~Surya

Tuesday, July 23, 2013

Factories for Dummies

Today I was working on swapping a single threaded implementation of a piece of code to multithreaded version. Apart from concurrency issues, one exercise I've gone through was to use factories. Factories naturally facilitate the way we inject dependencies into our business logic. In order to make the previous statement more clear, lets go back to our awesome calculator service. It exposes an 'add' API. Let's start with a bad abstraction,

public class AwesomeCalculator {

    public long add(long a, long b) {
        Adder adder = new SimpleAdder();
        return adder.add(a, b);
    }
}

public Interface Adder {
    long add(long a, long b);
}

public SimpleAdder implements Adder {

    public long add(long a, long b) {
        //do something simple and stupid
    }
}

The client would do something like,

public class AwesomeCalculatorClient {
    private final AwesomeCalculator calculator = new AwesomeCalculator();

    public void foo() {
        calculator.add(1l, 2l);
    }
}

Now lets say we've got enlightenment and want to make our AwesomeCalculator use a better Adder implementation. The first place we've to update is the step inside add() method in AwesomeCalculator. The programmer who wants to do this change would want us to rot in hell for the poor design. It is just a one line change in this example, but think about a real piece of software where we'd end up changing all over the business logic wherever we've had assumptions about SimpleAdder. More importantly, it is almost impossible to mock out Adder in our unit tests.This is a total nightmare. Lets call our friend 'factory' to the rescue.

A decent version of our AwesomeCalculator would look something like,

public class AwesomeCalculator {

    private final AdderFactory adderFactory;

    public AwesomeCalculator(AdderFactory factory) {
        this.adderFactory = factory;         
    }

    public long add(long a, long b) {
        Adder adder = adderFactory.getAdder();
        return adder.add(a, b);
    }
}

public class AdderFactory {

    public Adder getAdder() {
        return new BetterAdder();
    }
}

With this version, we could modify the factory to produce a better Adder implementaion thus moving the change out of our AwesomeCalculator. To make the code more pretty, we can go one step further. Lets try one more revision.

public interface AdderFactory {
    public Adder getAdder();
}

public class StupidAdderFactory implements AdderFactory {

    @Override
    public Adder getAdder() {
        return new StupidAdder();
    }
}

public class BetterAdderFactory implements AdderFactory {

    @Override
    public Adder getAdder() {
        return new BetterAdder();
    }
}

This is even better, since we've completely moved the change to the client side. If the client wants a new implementation of Adder to be used, we just need to create a new factory which is capable of generating that Adder and let the client pass the new factory to AwesomeCalculator. Sweet isn't it ?

What have we done ?
  • Separated the concerns nicely.
  • Made the code constructor injectible. This will be super handy if we use framework like Spring which does inversion of control.
  • We can write clean unit tests by easily mocking out dependencies.
Ciao,
Surya.

Friday, July 19, 2013

Iterators are your friends!

We all know that Iterators nicely decouple the container from the implementation details of traversing the container. Today I was optimizing an existing piece of code and had to work through the details this post talks about.

More about Iterators here. I’m going to talk about  a specific advantage of using iterators – improved testability of the code.

Let’s consider this simple class AwesomeParser. It keeps an InputStream and reads tokens from the stream. The stream has a header which contains the number of tokens in the stream.

class AwesomeParser {
    private final InputStream fileStream;
    private int numberOfTokens;
    private int tokensRead;

    public AwesomeParser(fileInputStream) {
        fileStream = fileInputStream;       
        numberOfTokens = 0;
        tokensRead = 0;
    }

    public void readFileHeader() {
        numberOfTokens = extractTokensCountFromFileHeader();
    }

    public Token read() {
        Token token = parseTokenFromFile();
        tokensRead++;
        return token;
    }

    public boolean hasMoreTokens() {
        return tokensRead < numberOfTokens;
    }
}

A sample consumer of this class would look something like,

class Consumer {
    private  final AwesomeParser parser;
    
    public Consumer(AwesomeParser parser) {
        this.parser = parser;
    }

    public void fooBar() {
        AwesomeParser parser = new AwesomeParser(fooStream);
        parser.readFileHeader();
        while (parser.hasMoreTokens()) {
            parser.read();
        }
    }
}

Looks like a nice abstraction. Now let’s see how the unit tests for our consumer would look like.
  • We mock out the parser.
  • Now the only way to test fooBar() is to make hasMoreToken() return different values for different calls. For e.g,
when(parser.hasMoreTokens()).thenReturn(true).thenReturn(true).thenReturn(false);
when (parser.read()).thenReturn(dummyToken);
Wait a second, what would happen if I modify fooBar() to something like,

public void fooBar() {
    AwesomeParser parser = new AwesomeParser(fooStream);
    parser.readFileHeader();
    if (parser.hasMoreTokens()) {
        log(“Woohoo work to do”);
    }
    while (parser.hasMoreTokens()) {
        parser.read();
    }
}

We have broken our assumptions about hasMoreTokens() in fooBar(). The unit tests will start failing one after another as they are so brittle. So, what do we do now? Iterators to the rescue :)

Let’s redesign our AwesomeParser.

class AwesomeParser implements Iterable {
    private final InputStream fileStream;
    private int numberOfTokens;
    private int tokensRead;

    public AwesomeParser(fileInputStream) {
        fileStream = fileInputStream;       
        numberOfTokens = 0;
        tokensRead = 0;
    }

    public void readFileHeader() {
        numberOfTokens = extractTokensCountFromFileHeader();
    }

    private Token read() {
        Token token = parseTokenFromFile();
        tokensRead++;
        return token;
    }

    private boolean hasMoreTokens() {
        return tokensRead < numberOfTokens;
    }

    /*  Warning: Usually you don't keep the traversal state of a container
     *  outside the iterator. The code will miserably fail if some one
     *  calls iterator() on AwesomeParser multiple times, since we have 
     *  one single underlying stream. You can always create a deep copy of
     *  it in the constructor of AwesomeParserIterator.
     */
    public Iterator iterator() {
        return new AwesomeParserIterator();
    }
    
    class AwesomeParserIterator implements Iterator {

        @Override
        public boolean hasNext() {
            return hasMoreTokens();
        }

        @Override
        public Token next() {
            return read();
        }

        @Override
        public void remove() {
            // never mind
        }
    }
}

Let’s try this abstraction. If we have to unit test the consumer of our new design,
List <Token> tokens = new ArrayList<>();
//populate tokens
Iterator <Token> mockIterator = tokens.iterator();
when (AwesomeParser.iterator()).thenReturn(mockIterator);
Essentially we have covered the underlying parser’s stream with a simple dummy list of tokens and faked the iterator returned by our AwesomeParser with an iterator to our dummy list.

What have we achieved?

The unit tests are no longer brittle and would just test the behavior of the consumer of AwesomeParser and have no assumption about how we traverse. Neat isn’t it?

Ciao,
Surya.

Sunday, June 23, 2013

Behavior Driven Development (BDD)

Behavior Driven Development (BDD)
http://en.wikipedia.org/wiki/Behavior-driven_development

When I joined my team, BDD was the buzz word. Initially it didn't make sense to me since most of the time I ended up writing steps to test what I'm going to develop. Aren't unit tests enough to test the functionality of classes I write ?

Let's say I'm going to implement the world's best calculator service 'foobar' which will talk to the super computer 'Param Padma' to do calculations. Where should I start ?

Well, I'll think about my design, draw a bunch of UML diagrams in whiteboard, write my interface, write some unit tests, implement the interface, make the unit tests pass and hand it over to QA. Now it's someone else's headache. Then I release the service to public and oops something is broken. I fix it, hand it over to QA, fix works, release the patch. Oooops.. it's not even adding two numbers anymore. Customers get pissed off and eventually your service will go down the drain. Trust me, most developers would have gone through this vicious and error prone cycle. As a developer I need some confidence to make code changes, fix bugs, refactor, optimize. I need a safety net around my code. Writing functional tests is one way to placate the above scenario. The idea of BDD is to do the development backwards starting from writing the functional tests. 

To start with, we have to identify different features of our service and then identify independent testable scenarios in each feature. A feature file might look something similar to this for our awesome 'foobar',
 
Feature: Perform arithmatic operations

As a client of foobar
I should be able to perform calculations on numbers
So that I can use the results to do something awesome

Scenario: Add two numbers
Given I have two numbers 1 and 2
When I ask foobar to add the numbers
Then I should get back 3

Scenario: Divide two numbers
When I ask foobar to divide 1 by 0
Then I should get an error saying "divide by zero"
....
....

If somebody wants to know about what our service does, feature files will tell them a story. Essentially we enumerate the customer facing functionality of our service as scenarios. Next, we associate step definitions for each of the above steps using one of the BDD frameworks. I've tried cucumber. It is simple and effective. (It is also one of the examples of how not to write software, but that's a different story in a separate blog)
"Given I have two numbers" 
public void I_have_two_numbers(int a, int b) 
{ 
  setA(a); 
  setB(b); 
}
 
"When I ask foo bar to add the numbers" 
public void I_ask_foo_bar_to_add_the_numbers() 
{
  FooBar foobar = MyAwesomeServiceInterface.getFooBarClient(); 
  // This step will actually make calls to 'param padma' and return the sum unlike a mock service.
  setSum(foobar.add(getA(), getB()));
}
 
"Then I should get back"
public void I_should_get_back(int expectedSum) 
{
  assertEquals(expectedSum, getSum());
} 

When we run the test suite, for each step in feature file, the corresponding step definition will be executed. So what have we gained out of all these?

·         We have clearly defined the functionality of our service, so there is no room for scope creep during implementation.
·         Before even writing the service we'd know how painful/easy it is going to be for the users to interact with our service.
·         We are implementing what we test and not testing what we've implemented.
·         The success criteria are crisp. Just make the steps pass and our service is ready.
·         The quality of code is better since it is easily maintainable. 

I've been practicing this for a while and it makes development so easy. A close metaphor would be 'swimming with a life jacket on'. Ciao in another post.

~Surya