not a dichotomy

Sometimes I hear people debating the relationship between synchronous and asynchronous execution. Or maybe distributed vs client/server architectures.  The thing to remember, in both of these cases (and a few more), these things are not dichotomous – one is completely subsumed by the other.

Take, first, synchronous and asynchronous execution.  At the most important level, synchronous execution is just a special case of asynchronous execution – first you start the execution, then you immediately wait for it to finish.  It’s important to note, also, that this has nothing to do with re-entrancy or thread safety, as these are separate topics, but only concerns the ability to run something “asynchronously”.

The only difference is the assumptions you can make as the writer of something that is assumed to be asynchronous.  In general, we make the implicit assumption, in writing our own code segments (e.g. methods) that the external state of the program at the beginning of the function is the same as it is at the end of the function, barring any changes we made directly.  If we explicitly want to make this assumption (i.e. we assume that this isn’t an assumption), we generally place locks around important things or even mark the entire function as atomic (in languages that support this, like Java), and we also use snapshot models for taking read-only captures of data at any point.

The implication here is that there are really two assumptions to make.  If you assume the rest of the world cannot change in any way (as in you are the only person in the world at any point in time), then you don’t protect against other people acting.  Otherwise, you plan accordingly.

Note that a (working) function that is written with the assumption that the world might change mid-stream will work perfectly in the other world, although it might do a bit of extra work.  On the other hand, a (working) function that assumes the world will never change will often break in exciting (sarcasm) ways when the world actually does change.

Of course, in the real world, we often make such assumptions to make performance gains, but you should understand that the only thing special about assuming synchronicity is that your crap is going to break when that changes.

Also, as I mentioned before, I often hear people arguing over the benefits of client/server and distributed programming.  What people seem to ignore, however, is that client/server is just a really, really limited example of a distributed environment (that is, where the maximum length of any path in your connection graph is 1).

Again, the only real difference here is what you can gain by your assumption, i.e. you don’t have to write the code to handle distribution if you only assume two parties are ever involved at any one time, where one party is generally the superior of the other.

As before, a distributed application will generally work in a client/server sense as well, though a client/server model doesn’t really distribute all that nicely (think distributing databases, web servers, etc., and think about all the logic and hardware that has to go into synchronizing and controlling everything).  You may save time writing the client/server, but you can’t end up with a distributed system.

So synchronicity and asynchronocity aren’t two sides of the coin – one is a  tiny piece of the other.  Same with client/server and distributed systems.  What you are really asking is, do you want the sandwich or do you want the platter (for the non-Rochesterians – do you want the little bit of food or the feast)?  If you choose the feast, you will pay more, and you might not eat all of it (at least right away).  If you choose the sandwich, you’ll pay less initially, but if you get any hungrier, tough luck.

(The impetus for this entry were arguments about the various merits of source control systems – the overall point being that you can make a client/server source control system trivially from a distributed source control system, but you can’t go the other direction).

blog comments powered by Disqus