Sunday, November 26, 2017

Water Drop Anti-Pattern

In my previous entries, I presented two patterns that allow you to limit the number of messages sent over a queue: the Indiana Jones Pattern and the Hamburger Pattern. The first one filters data while the second merges it.
waterdrop.jpgOnce all your data is filtered and merged, messages still arrives individually, one after the other, on your queues. In some cases, it might introduce the Water Drop Anti-Pattern, where your data arrives like from a tap from which drops are falling one after the other.
Consider an application where you highest layer sends data through a network. Each individual message comes with a payload: it has a header which allows it to arrive to the correct destination. The smaller the message, the highest the payload.
If your highest layer is a user interface, your message will also have a payload: the repaint method which needs to be called after each update. Usually, this is the most expensive operation in your interface.
Next time, I will show a way to solve this problem: the Santa Claus Pattern. Wait for it!

Saturday, November 18, 2017

Hamburger Pattern

Last time, I introduced the Indiana Jones Pattern, where you would filter your messages in order to send less data on your overcrowded queue.
hamburger.gifAnother way to reduce the number of messages is to use the Hamburger Pattern. Instead of separately sending the beef, the salad, the onion and the lettuce, why not send a complete hamburger at once? Imagine you are sending coordinates through the network. If you have two messages in your queue, one updating X, and another updating Y, you can merge both messages into one sending both coordinate changes at the same time. In the same way, if you have two messages, both updating X, you can also decide to merge them, sending only the second update.
This is more difficult than filtering, since you need to have access to your message queue and be able to remove messages from the middle. The default implementation of Thread Pools in Java uses queues that are optimized for adding at the end and removing from the front. Here, you will clearly need a different implementation.
public class Display {
    public void run() {
        while (true) {
            Data data = queue.getNextMergeValue();
            show(data);
 }
    }
}
After you filtered and merged all your data, you might end up running into the Water Drop Anti-Pattern. Next time!

Sunday, November 12, 2017

Indiana Jones Pattern

In my previous entry, I presented the Indian Train Anti-Pattern, where we add without discrimination data to handle on our queues, leading to overcrowded queues.
indiana.pngOne possibility to alleviate the problem is to use the Indiana Jones Pattern. In his Last Crusade, Indiana Jones had to go through three trials in order to prove himself worth of the Graal. We can imagine data going through a similar process to prove themselves worth of the access to the queue. We are in fact introducing a filter.
For instance, we do not wish to add to our queue an event telling us that data was not modified. Another example would be to send an event to our UI to notify of a data change for an item that is not even visible on the screen. We can imagine a large table with 10000 lines, but only 100 of them are displayed at a time.
public class Display {
    public void show(Data data) {
        Data prevData = getPrevData(data);
        if (data.equals(prevData)) return;

        if (!isDisplayed(data)) return;

        SwingUtilities.invokeLater(() -> table.updateRow(data));
    }
}
This is one way to reduce the size of the queue: drop some of the events. Next time we’ll see another way: the Hamburger Pattern. Stay tuned!

Sunday, November 5, 2017

Indian Train Anti-Pattern

Last time, I talked about the Marsupilami Pattern, where we introduce queues to transport data between application layers.
indiantrain.gifNow you’ve been using these queues for some time, conveying all sorts of data, and you realize that they are getting quite crowded, like those Indian Trains we see sometimes on TV. So crowded that people are standing on the roof. You might think that this is not a problem. Those are internal queues, so you can handle all this data internally, adding some more memory. Data might lag a little, but you are not doing “real time”, some seconds do not hurt.
But what if the Indian Train enters into the UI Thread? What if your user clicks on the menu bar, and the mouse events ends up at the end of the train. Would he want to use program where menus take several seconds to appear?
Or what if the Indian Train gets sent on the network? It might impact all the other applications sharing the network with yours, and they might not be happy playing the role of those sacred cows watching the Indian Train pass.
But what is to be done? Your Display class, for instance, is quite straightforward:
public class Display {
    public void show(Data data) {
        SwingUtilities.invokeLater(() -> table.addRow(data));
    }
}
Data is received, data is displayed. So simple. But sometimes, simplicity is too naive. One possible solution is to use the Indiana Jones Pattern. Wait for it!

Wednesday, November 1, 2017

Marsupilami Pattern

In my previous entry, I described the Paratrooper Model, where each application layer would have its own thread pool for handling data. And the way to implement that is to use the Marsupilami Pattern.
marsupilami.gif
It might be that you haven’t heard of the Marsupilami. You have to know that there are three countries in the world where comic strips are akin to a cult: the US with Marvel and DC Comics super heroes, Japan with their mangas, and France. Growing up in France, my childhood was populated with comics characters such as Asterix, Tintin, Lucky Luke, or the Smurfs. Or the Marsupilami, a creature half way between the jaguar and the monkey, living in the Amazonian forest and who solves all his problems using a very long tail.
That makes for a nice pun in French, since we use the same word for tail and for queue, and here, we will solve our Paratrooper Model problem by introducing a queue. Each application layer is separated from the next one by a queue. When data is handled, we just push it to a queue, from which next layer’s threads will draw, while we can concentrate on our next data.
In Java, this is really easy. If we go back to our Calculator class from last time:
public class Calculator {
    private final Executor executor = Executors.newFixedThreadPool(5);

    public void push(Data data) {
        executor.execute(() -> calculatePrice(data));
    }

    public void calculatePrice(Data data) {
        data.price = data.unitPrice * data.quantity;
        Display.show(data);
    }
}
The important line here is the one where we create a new Executor. In Java, with this one line, you create two things: a thread pool, and a queue (the Marsupilami’s tail).
But beware, if you do not pay enough attention, you might end up with the Indian Train Anti-Pattern. Stay tuned!