Skip navigation.

Notes to self

Whatever I feel like writing

Absolute Basics of Concurrency Correctness

,

Writing correct concurrent code is hard. Writing correct and performant concurrent is significantly harder still, but before getting to that, the code must first be correct. Actually, even correct in the non-concurrent sense. Simply put, the set of potential bugs - failure modes - in a multi-threaded program is the set of failure modes for the single-threaded program, plus all of the concurrency specific failure modes.

So, a correct multi-threaded program implies a correct program in general. But in this post, I will only focus on the part that is specific to correct concurrency.

Getting concurrency right takes knowledge and analytical skills. I am an avid TDD practitioner, and I try to test-drive as much as I possibly can. However, in the world of concurrency we are faced with the problem that some bugs are simply impossible to write a test case for. Sometimes the timings required to surface a bug are just too tight and the chances too small, other times a bug is just does not exist on our specific combination of hardware and runtime.

Therefore, analyzing the code in terms of the concurrency guarantees provided by the underlying platform, is a key element of the path towards concurrency correctness. And it cannot be done without knowledge of the guarantees provided by the platform, whether it be the JVM, CLR or x86.

There are lots of failure modes specific to mutli-threaded programs. Many are quite esoteric, but three things stand out as the most basic problems: shared mutable state, publication and locking.

The first problem of concurrency is shared mutable state. There are cases where you can have deliberate under-synchronized shared mutable state, but those are as few as they are special. There are basically three ways to deal with shared mutable state:

  1. Make state immutbale
  2. Don't share state
  3. Guard the shared mutable state by the same lock (two different locks cannot guard the same piece of state, unless you always use exactly these two locks)


The second problem of concurrency is safe publication. How do you make data available to other threads? How do you perform a hand-over? You will find the solution to this problem in the memory model of your platform and (hopefully) in the API. Java, for instance, has many ways to publish state and the java.util.concurrent package contains tools specifically designed to handle inter-thread communication. Make sure to give this problem ample focus; the bugs produced by unsafe publication can be extremely subtle, and it is easy to gloss over this problem and focus on locking instead.

The third (and harder) problem of concurrency is locking. Mismanaged lock-ordering is the source of dead-locks. Some dead-locks are practically guaranteed to always occur, while others require highly improbable timing. This problem can actually be generalized to everything that prevents a thread from making progress. Blocking operations, waits on conditions, spin-locks - these all have the same potential to stall a thread. And in this highly networked world, two threads don't even have to be on the same machine to dead-lock each other.

You can get pretty far with carefully constructed automatic test cases - and you should, but analysis is by far the most important step towards correctness in a multi-threaded program. However, you need to design and write your code with that in mind, otherwise the complexity of the code can quickly render such an analysis impossible to perform in practice.

How to grab the certificate from a website and import it with Java keytool

, ,

This is another one of those things that are impossible to remember.

For the record, the OS I'm using here is Ubuntu Linux, so the commands and paths will be different if you happen to be on Windows (keep googling, I know that a page is out there for you).

Step One is obviously to go grab the certificate from the web server. We'll use openssl, the tool, to dump the security information we need:

$ openssl s_client -connect that-server.com:443 > cert


Now open the newly created "cert" file in a text editor and remove everything but the blob that looks like this, but with different data in it:

-----BEGIN CERTIFICATE-----
MIIDIjCCAougAwIBAgIQbt4NlJn3RTPdEpf8Qqk74TANBgkqhkiG9w0BAQUFA8Bn
[... etc, etc, etc ...]
byB0lP6qDtnVOyEQp2Vx+QIJza6IQ4XIglhwMO4V8z12Hi5Fprw=
-----END CERTIFICATE-----


This cleaned up file is now the certificate that you want to import.

Step Two is to find the key-store that your Java installation uses (google will tell you that this file is called "cacerts"):

$ locate cacerts
/etc/java-1.5.0-sun/security/cacerts
/etc/java-6-openjdk/security/cacerts
/etc/java-6-sun/security/cacerts


So I obviously have more than one keystore because I have more that one version of Java installed. I use the "java-6-sun" version by default. The command
$ update-alternatives --display java
will tell you which version is your default.

Step Three is to finally install this certificate into the keystore. This command ends up doing it for me:

$ sudo keytool -importcert -keystore /etc/java-6-sun/security/cacerts -alias that-server -file cert


You will be asked for a password to access the keystore. By default, this keystore password is changeit - another thing easily forgotten.

And now your JVM should be able to create secure connections without those pesky SSL exceptions.

Killing VHDL highlighting in gEdit

GEdit, the "Text Editor" program in Ubuntu and other Gnome based Linux distributions, has an annoying habit of highlighting far too many non-VHDL files as VHDL. One of the file types it is particularly keen on highlighting incorrectly is SQL files. This is a pain because I use those a lot, wheres I have never had, and most likely never will have, any use at all for editing VHDL files.

So I decided to figure out how I could disable that highlighting mode once and for all. This is what I came up with on my Ubuntu Hardy box:

sudo rm /usr/share/gtksourceview-2.0/language-specs/vhdl.lang

Then restart gedit and everything VHDL'ish about it will be gone.

NanoPool Benchmark

,

Had the opportunity to test NanoPool on an 8-core machine today. The primary purpose was to decide between two possible fixed for gh-issue #8 (a connection leak was possible with unlucky timing between a pool resize and shutting the pool down).

The test was a success overall, but a pattern emerged from the data that highlighted an undesirable behavior.



The three major humps in this chart shows three different sets of test runs, with a varying threads-to-connections factor (the X-axis number). As it turns out, the pool will show a negative throughput scaling when the number of threads accessing the pool concurrently exceeds the number of connections. The Y-axis number is the number of open/close cycles that can be squeezed through the pool in 650 milliseconds.

The reason is probably that the default ContentionHandler have a relatively high spin-rate for undersized pools. The high spin-rate will burn CPU resources that could otherwise be used by other threads to complete their work and let their connections return to the pool.

This effect is a property of NanoPools lock-less design, and I'm not sure if it is possible to deal with this behavior without compromising that principle. But one thing is certain: when you create a pool, make sure it's big enough (or use a resizing ContentionHandler).

If the pool had handled the contention ideally, the third hump would be roughly equal to, or only slightly less than, the second hump.

Video links

, , ,

Four Kinds of Tests for Basic Correctness

, ,

This is from J. B. Rainsbergers talk Integrations Tests Are a Scam, which by the way is a great talk that is very worth watching.

Rainsberger defines three kinds of tests:
  1. Collaboration tests
  2. Contract tests
  3. State-based tests

I would like to add a fourth kind to that list, called the Concurrency tests.

Let me try to explain what each of those are about, in turn.

Collaboration tests: I talk to a bunch of other guys and, assuming they work correctly, am I working correctly? In essence, we are testing the correct behaviors of the individual units in our system, under the assumption that all other units work correctly in accord with their contract.

Contract tests: someone uses this thing in a certain way and expects a certain behavior from that, do you live up to that contract? In essence, we are testing that the units use each other correctly. In other words, that we have gotten the links between the collaborators right.

For example, if we have ThisThing that expects ThatThing to return an empty list under certain conditions, then we would mock the world as such in our collaboration tests but we will make sure that this assumption holds, in our contract test. In other words, we must have a test that sets up ThatThing in those certain conditions and verifies that it really does return and empty list, and not something else, like null or a list with something in it.

State-based tests: doing someAction to someThing must produce thisObservableEffect. These are the good old super simple tests for pure functions, or very simple state mutations, or side-effects to the outer world.

Concurrency tests: like state-based tests, except the observable effect is some specific behavior of the unit under concurrent use.

Concurrency tests makes sense to separate from state-based tests because a) things that deal with concurrency should deal with nothing else, and b) testing for specific concurrent behaviors is typically harder and more complex than single-threaded state-based tests and if they are not then you are doing something horribly wrong with your state-based tests.

If you do these tests, and design your system this way with all these things ind mind, then, Rainsberger postulates, you will only need integration tests as a debugging tool for figuring out which contract or collaboration tests are either missing or wrong. And once that issue has been fixed, you will have a focused object test that covers the same exact case as the integration test did and so you remove the latter to get rid of the duplication.

I must say that that sounds like a very nice place to be.

Responsive Design

,

I just read Kent Becks article in the third issue of PragPup Magazine called Responsive Design.

His points ring very true with me and I am looking forward to seeing his results become a book at some point.

The fundamental thesis is that software design is not created through a rational process. Rather, the design emerges, guided by the programmer, as a response to the problem at hand.

Our illusion of control over software design is a dangerous conceit best abandoned.



To think that we are controlling the design of our software is a lie. It is this lie that leads us to believe that we can create big detailed class diagrams before the first line of code is written, and believe that they resemble anything but a fantasy.

There is a very simple way to illustrate why these upfront designs don't work. See, design exists to solve problems. The solution exists because the design does. The design causes the solution to be - brings it into being, but not only it. With a design comes also flaws and imperfections. A design contains decisions, some of which are good, some may be bad and some are compromises. A design causes not only solutions, but also new problems.

These problems may be bug or they may be limitations of sorts, but if we want them solved we will need a design. As this cycle continues, it becomes increasingly difficult to predict and describe problems and design with any level of accuracy. And as fate would have it, we really only have two levels of accuracy: accurate, or not. Even the tiniest assumption can have vast consequences for a design - only with runnable code can we really know what the truth is.

Design is not a rational process.



Design grows in response to problems. Responsive Design. But the design is not chaotic. Consider a plant: it is not design - no one can say before the seed is planted, how, exactly, it is going to look. It will grow in what way it finds most meaningful in an effort to solve the problem of survival. But its growth is not chaotic. It has definite lines, purpose and structure. It has parts that are connected in purposeful and meaningful ways.

In short: there is meaning and intent behind the growth of a plant. Likewise, there is meaning and intent behind the growth of a software design. Kents Responsive Design Project is about uncovering and coming to grips with that meaning.

Thoughts on Corey Haines talk with JBrains

,

This post is just to collect my thoughts on Corey Haines' talk with J. B. Rainsberger on moving specificity towards the test.

Rainsberger presents these four elements of simple design:

  • Passes test
  • Minimizes duplication
  • Maximizes clarity
  • Is small

If we are doing TDD as Uncle Bob prescribes, in very short red/green/refactor cycles, then the "passes test" part becomes a non-issue and goes away. Then, the "is small" goes away because any body of code that has minimized duplication and maximized clarity is unlikely to be unnecessarily large.

This leaves us with these two takeaways from the talk:

  • Focus on removing duplication leads to well structured code.
  • Focus on bad names and clarity leads to a good distribution of responsibility.

Removing duplication is not just code, but also intent. Say and Inventory knows how to format prices, while some controller object knows how to write "No price available" if the Inventory could not find a price for some product. Both of these deal with how to present a price, but they deal with different parts of the presenting. So there is no duplication in the code, but there is duplication in the intent. Both of these pieces of functionality could moved to a view or presentation layer, and then combined into a whole. This removes the duplication of intent.

It sounds like an application of the single responsibility principle, and that's not a bad thing.

As part of the process of removing duplication, one can start by moving the duplicated parts closer to each other. Say we have a Catalog object that knows how to turn barcodes into prices. If I have a test where I pass in a certain barcode and expect to get back the price 12, I could initially just hard-code the number 12 into the Catalog. As I test for more and more barcodes, this turns into a lookup table. Then we can notice the duplication of the hard coded values. If the lookup table is really a map underneath, I can move it to the test and then pass it into the Catalog through the constructor.

This in turn leads the code to naturally evolve toward a model-view-control design. The concerns needs to be separated so they can be passed in and stubbed if need be.

Bad names and clarity is a bit harder to grasp. Frankly, the way he describes things makes it hard to see design effects are caused by removing duplication and which are caused by gaining clarity. So it ends up getting mixed together in his explanation. To me, the structure of the code and the distribution of responsibility are two sides of the same coin. It can be that he meant to say that this is the way it should be. His example of the MVC structured code where the intent and logic of formating prices is duplicated and located in multiple different places, seems to support this conclusion.

The "ClassThat" Naming Convention

, , ,

I have noticed a pattern in my unit-testing recently. Ah, the word "pattern" is possibly a tad loaded for this purpose, so you might also call it a trend, a style or a convention. It's a recurring thing anyways, and it has to do with how I build my mock objects in my unit tests. I write primarily in Java, by the way, so this is where I noticed this pattern but it may just as well apply, with or without modification, to other languages.

Onwards.

The gist of it that if I have some class called a "Peg" that is used in all sorts of situations throughout my code and I need to build mocks of it for testing, then I will create a companion class called "PegThat" in the test sources tree.

This "PegThat" class will consist of nothing but static methods that all return various forms and instances of Pegs. These static methods will have names telling of certain properties of the Pegs they return. For instance, it might have an "isSquare" method that returns a square Peg.

The beauty of this naming convention is the readability that ensures in my test code. Behold:

@Test public void
squarePegsMustFitIntoSquareHoles() {
  Peg peg = PegThat.isSquare();
  Hole hole = HoleThat.hasEdges(4);
  
  assertThat(peg, fitsInto(hole));
}


That is arguable a very contrived example, but when you are building more complex mocks or instances, and these static methods need parameters or various types, then the benefit increases. Your tests can become a lot less messy and a good deal more readable.

Form Follows Function

, ,

If form follows function then why do we do up-front design when we develop software?

My work place has, for some time now, repeatedly asked me for estimates and designs, and this has gotten me to think about how I feel about those artifacts. In this blog post I am going to try and put my feelings about up-front design into words.

Design is the detailed description of how something is suppose to be built, but software development is plagued by uncertainty to such a degree that any design conceived before the first line of code has been written, is bound to be wrong.

Design is a model and a description of a destination. A place we want to end up. A model and a description of what we want to end up with.

When one embarks on a new software development project, I would argue that such a destination is not a terribly valuable artifact to have. Kent Beck uses the metaphor of driving to describe software development; constantly adjusting the direction as we go, making sure that we don't fall off the road.

Kent Beck is spot on, in my opinion. We don't need a destination when we start a project. What we need is a starting point and a direction. And the people that need those things are the team members, not management. The team members all needs to be on the same page with regards to the starting point and the direction. This is even more so important with a distributed team, which is what I currently have at hand at work.

When the starting point and the direction is all agreed upon, then the destination, the design, will emerge as we go along, and become self evident when we at some point decide to stop. This is the "emergent design" idea from extreme programming.

But before I get ahead of myself here, I have already described how design is the destination in this metaphor, so what are the starting and the direction? Briefly, the starting point is the most pressing and important unimplemented user story. The direction is knowledge of the business problem and a vague conceptual idea of how a system might solve this. I suppose part of what the direction is, is described in the current set of unimplemented user stories, but the direction as a whole is more than just user stories. The direction is sense that all team members are "on the same page," so to speak.

So when I title this blog post as "Form Follows Function," what I really mean is that "Design Follows Implementation" and that this idea is emergent design. When we write code, we are also implicitly designing, and this design that emerges from our code is the real design, so to speak. It is the truth, as oppose to some up-front class diagram describing classes that don't exist and incorporating engineering trade-offs to problems that also don't exist (unless they are designed into the system).

The up-front design describes either something that we don't want, or something that we won't get, or both. And therefor, I think that working to the level of detail that is implied by it, is wasted effort. And I don't like wasted effort.