You've been warned...
Friday, August 27, 2010
Monday, May 24, 2010
Data Interaction Patterns
As you know, when data is involved caching comes into play when performance and scalability are sought. In the coming diagrams, cache is represented as a vertical rectangle. The persistent storage is represented as a vertical blue cylinder, while horizontal cylinders represent some form of reliable and asynchronous message delivery channels. The data interactions are represented with curvy arrows: they can represent reading or writing.
Direct [R/W]
Besides the obvious drawbacks coming from the temporal coupling with the persistent storage mechanism, the interesting thing to note in such a trivial data access pattern is that there is often some form of request-scoped caching happening without the need to explicitly do anything. This first level of cache you get from data access layers help in optimizing operations provided they occur in the same request (to which is bound the transaction, if one exists).
Being short lived, this kind of caching is free from the problem of expired cache entries eviction: it can kick in transparently without the application being aware of it.
Through Cache [R/W]
Reading through cache is a simple and powerful mechanism where an application tries first to read from a long lived cache (a very cheap operation) and, if the requested data can't be found, proceeds with a read in the persistent storage (a way more expensive operation).
It's interesting to note that write operations don't necessarily happen the same way, ie. it is well possible that a write to the persistent storage doesn't perform a similar write in the cache. Why is that? Cached data is often a specific representation of the data available in the storage: it can be for example an aggregation of different data points that correspond to a particular cache key. The same persistent data can lead to the creation of several different cache entries. In the case, a write can simply lead to an immediate cache flush, waiting for subsequent read operations to repopulate these entries with new data.
Conversely, it's possible to have write operations update the cache, which opens the interesting problem of consistency. In the current scenario, the persistent storage remains the absolute truth of consistency: the application must handle the case when the cache was inconsistent and led to an invalid data operation in the persistent storage. I've found that localized cache evictions work well: the system goes through a little hiccup but quickly restores its data sanity.
Though some data access technologies allow the automatic management of this kind of second level of caching, I personally prefer that my applications have an explicit interaction with the caching technology they use, and this at the service layer. This is especially true when considering distributed caching and the need to address the inherent idiosyncrasies of such a caching model.
This said, stickiness skews load balancing and doesn't play well when you alter a pool of servers: I've really became convinced that you get better applications by preventing stickiness and letting requests hit any server. In that case, cache distribution or clustering becomes necessary: the former presents some challenges (like getting stale data after a repartition of the caching continuum) but scales better than the latter.
Write Behind [W]
Writing behind consists in updating the data cache synchronously and then defer the writing to the persistent storage to an asynchronous process, through a reliable messaging channel.
This is possible with regular caching technologies if there is no strong integrity constraints or if it's acceptable to present temporarily wrong data to the data consumer. In case the application has strong integrity constraints, the caching technology must be able to become the primary source of integrity truth: consistent distributed cached that supports some form of transactional data manipulation becomes necessary.
In this scenario, the persistent storage doesn't enforce any form of data constraint, mostly because it is too hard to propagate violation issues back to the upstream layers in any meaningful form. One could wonder what is the point of using such a persistent storage if it is dumbed down to such a mundane role: if this storage is an RDBMS, there is still value in writing to it because external systems like a back-office or business intelligence tools often require to access a standard data store.
Cache Push [R]
Pushing to cache is very useful for data whose lifecycle is not related to the interactions with its consumers. This is valid for feeds or the result of expensive computations not triggered by client requests.
The mechanism that pushes to cache can be something like a scheduled task or a process consuming asynchronous message channels.
Future Read [R]
In this scenario, the data producers synchronously answers the consumers with the promise of the future delivery of the requested data. When available, this data is delivered to the client via some sort of server push mechanism (see next section).
This approach works very well for expensive computations triggered by client requests.
Server Push [R]
Server push can be used to complement any of the previous interactions: in that case, a process prepares some data and delivers it directly to the consumer. There are many well known technological approaches for this, including HTTP long-polling, AJAX/CometD, web sockets or AMQP. Enabling server push in an application opens the door to very interesting data interactions as it allows to decouple the activities of the data consumers and producers.
Monday, May 17, 2010
Infected but not driven
There are some interesting discussions going on around TDD and its applicability, which I think are mostly fueled by the heavy insistence of TDD advocates on their particular way of approaching software development in general and testing in particular. The more time I spend thinking about these discussions, the more it becomes clear to me that as far as testing is concerned, the usual rule of precaution of our industry applies: ie. it depends.
Behavior
Public Interface
When creating non-trivial public functions, I've found a great help into going through a serious amount of code reading in the different places where it is envisioned these functions will be used. Reading a lot of code before writing a little of it is commonplace in our industry: while going through the reading phase, you're actually loading all sort of contextual information in your short term memory. Armed with such a mental model, it becomes possible to design new moving parts that will naturally fit in this edifice. So that I guess that practice would be RDD (reading driven development).
Friday, May 14, 2010
Just Read: Zabbix 1.8 Network Monitoring
Friday, April 30, 2010
Grafting Mule Endpoints
Note: The following code samples are applicable to Mule 2.
In Mule ESB, outbound dispatching to a destination whose address is known at runtime only is a pretty trivial endeavor. A less frequent practice consists in programmatically defining inbound service endpoints.
- The class implements MuleContextAware in order to receive an instance of the MuleContext, which is the key to the gate of Mule's innermosts. Some might consider fetching this class from the connector object that gets injected in this class too: I personally find this less desirable for design reasons that I'll let Demeter explain.
- The endpoint is bound to the desired connector by passing its name in the URI used to create it. This allows picking up the right connector, which is compulsory for any Mule configuration with more than one instance of a particular connector (file connectors in this case).
- Endpoint specific configuration parameters, like moveToDirectory, are configured as extra URI parameters. You can also add other parameters, as key/value pairs: they will be automatically added to the message properties dispatched from this endpoint.
Wednesday, April 28, 2010
Just Read: 97 Things Every Programmer Should Know

If you're familiar with the practices that the Agile, XP or Software Craftsmanship movements are putting forward, you'll find that you already knew and agreed with most of the book. In that case, the real value of this book will come from the few essays you'll find questioning or disagreeing with, as you will have to self-introspect and decide if your disagreement is founded or based on prejudices.
Tuesday, April 20, 2010
Wednesday, April 14, 2010
Just Read: Coders at Work

Thursday, February 25, 2010
The Holy Grail Of Persistence?
- Schema Migration - For a startup, it's critical to be able to evolve a database schema with the less friction possible as features are often in a state of flux.
Using a standard DB like PostgreSQL allowed us to leverage Ruby's ActiveRecord Migration, which is not only handy for migrating forward (as you do in production) but also backwards (as you sometimes have to do in development). Though Mnesia record evolution is possible, the fact that data migration concerns permeate into the application code is very unpleasant. Going schema free was a tempting option but would not have come close to the flexibility ActiveRecord and PostgreSQL gave us. - Supporting Resources - Being able to solve problems quickly is essential for a startup: for everything that is not your core business, you usually rely a lot on the information available out there.
PostgreSQL has an extensive body of knowledge available online and in print. When things go haywire or in case of doubt, you're pretty much guaranteed that a Google search will bring you at least a couple of pages where people asked the exact same question and got answers for them. With Mnesia, the amount of available information is way reduced, simply because it's still very much a niche database. - Standard Connectivity - When you're focused on building something new, the last thing you want is wasting time in re-inventing the wheel: interoperable building blocks are key.
Using an standard database like PostgreSQL gave us immediate access to tools like Pentaho's Data Integration, which we use to massage data. Though we could have built an army of supporting tools to perform the same on Mnesia, it's always better to use something that's already there. I has also allowed us to fully leverage Ruby On Rails to build an awesome back office in no time. Though there are some Ruby-Erlang bridges out there, none gives you all the RAD features you get when plugging Rails to a standard database. - Operational Simplicity - In a startup, there's no DBA to nurse your database engine: you have to deal with it so it better be simple to operate.
Installing, upgrading, backing-up, restoring PostgreSQL databases are all well defined operations, supported by a wealth of tools. The security model is straightforward too. And there are plenty of options for monitoring what's happening under the hood and analyze and tune performances. I have no doubt all this is possible with Mnesia, but in a less familiar and straightforward manner.
Wednesday, January 06, 2010
Monitoring RabbitMQ with Zabbix
Wednesday, December 16, 2009
Is Test Overlap A Necessary Evil?
Another important point is that unit tests are a convenience for *you*, the developer, while functional tests are important for your *users*. When I have limited time, I always give priority to writing functional tests. Your duty is to your users, not to your test coverage tools.
You also bring up another interesting point: overtesting can lead to paralysis. I can imagine reaching a point where you don't want to modify your code because you will have too many tests to update (especially in dynamically typed languages, where you can't use tools that will automate this refactoring for you). The lesson here is to do your best so that your tests don't overlap.

As you can see, the overlap exists because tests of the upper layer rely on mocks to simulate all the happy paths and most of the unhappy paths of the underlying layer. The overlap is not total because a layer tend to reduce the granularity of the unhappy paths it faces internally in order to expose the upper layer to a limited amount of bad situations to deal with. Hence the limited amount of mocked features in the overlap area.

Now the application container is also tested, plus we get an insane amount of overlap.
Sunday, November 15, 2009
Zulu Zabbix
If, like us, you're running the Zabbix monitoring platform in Zulu time (aka UTC), you should have noticed a time glitch when displaying historical graphs.
The cause of this problem is simple: the fancy controls in the browser-based user interface are rendered using JavaScript, hence based on the time of the machine used to browse the graphs.
Though we are strict in running all our servers in Zulu time, we haven't crossed the chasm and decided to run all our workstations and the rest of our life in UTC. So here is the simple fix you can apply to js/sbinit.js
The idea is to simply add the local browser time offset to the Unix time. With this fix in place, you will enjoy good looking graphs and correct navigation in them.
Time is really the stumbling block of software engineering...
Wednesday, November 11, 2009
Meeedia Playeeer
Just when I started to consider building a player out of a SheevaPlug, I remembered of the ultimate source of cheap hardware, ready to be repurposed: eBay. $125 and a few days later I had a like-new black Asus Eee PC 2G Surf waiting to be turned into a music player.
The unit came with Ubuntu Eee Hardy Heron on it and only 50MB of free space left on its 2GB solid state drive. After a merciless review of all the installed applications, I ended up with 200 MB of free space, ready to host a music player.
Finding the right music player was no small feat.
I really enjoy Audacious on my work laptop because it's plain simple and is able to play music directly from an NFS mount without any glitch. But it lacks an integrated library manager, which is a must for any software powering a machine dedicated to playing music.
So I went on trying all the players with integrated music library manager I could find in the Heron standard software repository (I won't quote names because most of these applications have now better versions available). All of them were suffering from multiple woes rooted in their bad handling of network fluctuations. The most common issue was a too short not-configurable music buffer, leading to broken music replay. The worst issue was with a library manager that was not only taking ages to scan my 16+GB of music but also, on the first network glitch, would start to delete songs, one by one, from the partial library it had created (talk about defensive programming gone bad).
So I ended up installing Amarok. The reason why I didn't immediately install it, knowing it has been my favorite player for all the time I was on Kubuntu (until the KDE 4 debacle), is its sheer size. It's a 120 MB install and on an almost full drive it didn't feel like a good idea to try it first.
This turned out to be the perfect match! Not only Amarok plays music from my NFS mount without a glitch, but its music library is totally unaffected by disturbance in the Wi-Fi signal.All in all, my Eee Music Player is doing great. It only takes a few seconds to be resurrected after being suspended and music starts playing soon after.
Do you think repurposing full fledged computers into single application hosts is a crazy idea? Is it something you've considered or done already?
Saturday, October 31, 2009
Software Manifestos: A Matter Of Trust?
Here is a little game: match the manifestos with the software insanities they push back on:
| Big methodology and design up-front | Software craftsmanship manifesto | |
| Army of flying monkeys testing | Agile manifesto | |
| Snake-oil vendors and ivory tower architecture | QA manifesto | |
| Reckless programmers and incompetent coders | SOA manifesto |
If we dig deeper, we become tempted to ask why is our industry suffering from such insanities? What does make software different? Could it be because of complexity?
Complexity. Software entities are more complex for their size than perhaps any other human construct because no two parts are alike (at least above the statement level). If they are, we make the two similar parts into a subroutine--open or closed. In this respect, software systems differ profoundly from computers, buildings, or automobiles, where repeated elements abound.Frederick P. Brooks, Jr., No Silver Bullet
The natural reaction to complexity is to try to escape it at all cost, even if it means wilfully practising self-deception. Hence silver bullets, hence snake oil vendors, hence all these methodologies, governance committees and ivory towers that are there to nurse the insecurity of higher levels of management by giving them the impression software creation is under control and, finally, out of the hands of programmers.
Of course, it doesn't work that way: years and millions of dollars later, reality comes knocking at the door, manifestos are getting written and everyone is sent back to the same fundamental question they've been trying so hard to avoid: how to build trust in software developers?
And that's of course a question for us, software developers. How can we build such a trust in us when so many forces are pushing towards the opposite?
Granted that software development is unpredictably complex and that this complexity reveals itself when the devil shows up (those pesky details), it is clear that the overall battle of trust is fought during each decision, when tackling each detail and writing each line of code.
I think we could learn a few lessons from the world of aviation, where trust in pilots has been built progressively and methodically. When you fly an airplane, you have plenty of decisions to make and losing any of these battles can end up very badly for everyone. So why are pilots trusted? Aren't they fully superseded by ATC anyway? Answer is no: even if ATC has authority, the PIC (Pilot In Command) has the last word because he is the one out there dealing with the ultimate reality of flight. Despite its authority, ATC doesn't micro manage the pilot: the pilot is in-command.
To have the privilege to be a PIC, you have to remain current and regularly prove that you can be trusted for your judgement based on your skills, experience and training.
If the acronyms didn't sound so bad, I would dare suggesting programmers should become DICs, ie Developers In Command. Though working under different forms of authority, DICs would be fully trusted for taking the final decisions in the daily battle of writing code. In this world, it wouldn't be an heresy to say that developers could build large and complex software systems from the ground up, without the need for snake oil, committees or big design.
When trust will be manifested, we won't need manifestos anymore.
Monday, September 07, 2009
Looking for my seams
In object oriented programming, this is a given thanks to polymorphism and dependency injection. But in Erlang, where SUTs are MUTs (modules under test) and the common idiom for invoking a method is module:function(parameters), things are a little less obvious. Indeed, hard-wired function calls from one module to another don't leave much room for any kind of substitution. Without the capacity to fully test my modules in independence, I quickly started to feel uneasy. After a few days, it felt like free-falling without a parachute.
Then I started to seriously investigate my options...
Macros
Macros allow you to define blocks of instructions that the pre-compiler will substitute for you at the different places you refer them. When used in conjunction with flow control statements, macros can be used to switch one code fragment with another one by passing a parameter to the compiler. This seems to fit the bill as you can use conditional macros to alter behavior without editing the places where the macro is used.
This said, I have quickly ruled out the use of macros as a valid seam. Imagine having to do this for all the function calls leading out of the MUT:
Moreover, if a mistake exists in the non-unit test wiring part of the conditional macro, I would have had to wait for integration tests or actual deployment to get feedback on the issue.
Funs
Though the common idiom is to early bind the module and function you want to call, Erlang is fully capable of late binding and dynamic invocation, as this very crude example illustrate:
This opens interesting possibilities for MUTs that expose higher order functions. If the function that must be tested accepts one or several functions, passing a mock implementation is just a matter of providing an anonymous function of the same arity. This mock would perform nothing besides storing the received parameters in a shared storage, like the process dictionary, for later inspection.
Unfortunately, not all functions receive their dependencies as parameters but instead perform direct calls to other functions in other modules. It could be a plausible and drastic design decision to forbid all direct inter-module calls in favor of passing dependencies as anonymous functions via additional arguments. Some have suggested to use a record to pass around all your application dependencies as a single extra argument added to all functions.
Interesting but the idea of polluting all functions with additional arguments is less than palatable. In fact, it would great if these extra arguments could be defined module-wise and implicitly added to each of its functions... Rejoice! Parameterized modules have been introduced to perform exactly this delicious syntactic sugar trick!
Parameterized modules
I have discovered parameterized modules while writing controllers for Mochiweb. In this pretty cool HTTP server, the request reference that your processing function receives points to a parameterized module, allowing this kind of neat syntax:
Though this may feel object oriented, don't get fooled: behind the scene, there is no instance of anything. The Request reference contains all the hidden parameters that the get function needs besides the atom specifying what you want to get. Behind the scene, what really happens is more likely something like that:
But because the Mochiweb Request is a parameterized module, all the extra parameters have been specified once, packed in the reference and stay hidden there for your utmost convenience!
From there, it's easy to see how to write stubs for parameterized modules: just write another parameterized module that export functions with the same signature as the ones you use in the real module. Here is a very incomplete but fully working request stub for Mochiweb:
Note how I use the process dictionary to store values that I will later retrieve for asserting everything went as expected. By using parameterized modules, I have been able to reach near 100% code coverage. Does this mean parameterized modules are the best thing since sliced bread?
Well, so much for the free lunch as there are some drawbacks to consider:
- Experimental - Parameterized modules are still officially considered as an experimental feature of Erlang, hence subject to change. Unlike the Java world where everything is kept for ever just in case, Erlang doesn't patronize developers, so if this feature is one day bound to oblivion, it will be tossed out. And quickly.
- Unchecked - Unlike with a direct module's function reference, compile-time checking is not available, leading to possible bad surprises at runtime. If the parameterized module reference your code uses does not expose the expected function, you're in for a nasty error. In fact, you can totally pass a reference to a Foo module while your function expects a totally unrelated Bar module. As a tentative mitigation, I have added a verification function in my modules so they ensure at start-up time they are correctly wired. This feels like framework-envy,so I'm not fully satisfied with this approach.
- Confusing - Because the actual module is not directly referred to, reading such code becomes more complicated. You have to infer from the context (or some coding conventions, or even comments) what is the module that will actually be wired-in at runtime. Decreasing understandability is definitively not a good thing.
Besides these downsides, I still believe that the complete MUT isolation and behavior swapping facilities offered by parameterized modules make them a very interesting tool for the test-minded Erlang developer.
Closing notes
MUTs have other kinds of dependencies that you will want to substitute at unit testing time. To name a few:
- Process dependencies - A MUT can contain functions that directly depend on other processes via their PIDs (process IDs). An interesting seam here is the local registry of processes (and ports) that you can use to set-up test processes and register them under the same name as the ones used at runtime.
- Mnesia - Stubbing out calls from the controllers to the DAO is a good strategy but what about the DAO itself? Instead of stubbing out each Mnesia call, I have opted for running it in-memory at unit test time (à la hsqlddb) and activating file persistence only at runtime. This is extremely fast so very well suited for the task.
Finally, if you wonder what unit testing framework I am using, I have opted for etap, which I find very simple and powerful enough for my needs. If you want something more structured and feature-rich, EUnit is the answer.
Free fall is over: I have found my seams and landed seamlessly. Please share your own test infected adventures in Erlang.
UPDATE 23-SEP-2009: Hot code swapping is also a very powerful seam, that has been smartly leveraged to create ErlyMock, a quite capable mock framework for Erlang.
Saturday, August 15, 2009
Why Software Craftsmanship?
Wednesday, August 12, 2009
Zombie ESBs and the Integration Craftsman
During the past months, ToughtWorkers have been regularly pounding on ESBs in a manner that Martin Fowler has neatly summarized like this:
"Hang around my colleagues at ThoughtWorks and you soon get the impression that the only good Enterprise Service Bus (ESB) is a dead ESB. Jim Webber refers to them as Egregious Spaghetti Boxes. So it's not uncommon to hear tales of attempts to get them out of systems that don't need them."
The reasons for such a reaction to ESBs are multiple and, more often than not, very valid. I think they stem from two main issues: the proprietary nature of such platforms (see Ford's "Standards Based versus Standardized") and the architectural quagmire an excess of "enthusiasm" towards them can entail (see Dörnenburg's "Making ESB pain visible" and Webber's "Guerilla SOA").
The only problem I have with thought leaders pounding on ESBs is the negative aura it can create around developers involved in integration projects.
What? Why do I dare talking about integration while the subject is about ESBs? Well, both subjects have become intertwined because many so-called ESBs out there are simply re-purposed integration platforms. And by re-purposed I really mean deployed as an ESB topology because ESB is first and foremost a topology and not a product (as Ross Mason pointed out in "To ESB or not to ESB").
So can developers working on integration projects be real craftsmen? I think they can and I think they should.
This may sound a little naive but it's not. Consider the following:
- Integration has patterns. Thanks the work of Gregor Hohpe and Bobby Woolf, developers have access to a vendor-independent semantics under the form of the Enterprise Integration Patterns. Being able to model and discuss integration without referring to a particular implementation is invaluable for craftsmen.
- Integration has testing. It is oftentimes a challenge to test complex integration project and developers could be tempted to skip it altogether. Once again thanks to Gregor Hohpe, but with Wendy Istvanick this time, testing at all level of an integration project has been proven possible and documented.
- Integration does not preclude SDLC practices: one point we tried to make in Mule in Action, is that even if your project consists in configuring an integration tool, you should not cease to be a craftsman and you should exercise good judgment and abide by your professional standards. You want to shoot for no less than reproducible builds and deployments in your integration projects.
So, whether ESBs are better dead or undead, developers dealing with integration projects should strive to be software craftsmen above anything else.
PS. Isn't it ironic that Gregor is an ex-Thoughtworker?
Saturday, July 18, 2009
Mule in Action: Now Treeware!
Trees had to die to get us there by here we are: Mule in Action is now treeware. And in case you missed it, the making of was here.
Enjoy the reading!
Tuesday, July 07, 2009
Legacy Code Sonar Signature
To me, legacy code is simply code without tests.He also adds:
I've gotten some grief for this definition.Indeed, defining legacy code is hard.
After purging one of our project from code that we consider legacy (deprecated, EJB2...), we noticed this interesting trend in our Sonar dashboard:
Notice how code coverage is way less affected than complexity and rules compliance. Our legacy code had test coverage, not the greatest ever, but it had some.Therefore, I am wondering if we could then postulate that legacy code is code that has fallen short of software development standards?
This is actually what is expressed by the above graph: ditching legacy code drastically improved compliance to standards expressed as acceptable complexity and compliance to coding rules. These standards evolve over time: as legacy code is left abandoned, it slowly drifts away and gets less and less compliant by just standing still.
Have you noticed similar trends?
Monday, June 29, 2009
Demeter's Wrath and Angry Monkeys
Consider this freshly created method and notice how it asks for more than it needs, setting the stage for the upcoming drama that involves a fuming Demeter in her heavenly spa:
This method needs a country code to perform its unspeakable computation but asks for a User object. Why would anyone do that? Well, if User objects are common goods around the class that holds this method, it may look like a natural thing to do.
Inevitably, methods in other classes will have the need for a schniblitz to be computed for them. They will use the above method and will, therefore, need to provide a User object for them. And they may well be cool with that.
Now enter the angry monkeys. From dependency to dependency, the fact that a User object is needed to compute a schniblitz will get propagated. After a while, once the client call will be far enough from the original method, in another module or project, handled by a different team in another site, no-one will have the slightest clue why a User object is needed. But a barrage of classes will angrily ask for it.
So when an innocent victim comes around, it will be badly beaten if it doesn't present a valid User object in exchange for a nicely computed schniblitz.
But, for this victim, this may well be a big deal. Perhaps, it does not have a full User object handy, so it will need several database calls to completely build it so it can pass it and get its schniblitz. Or perhaps, it deals with NewUser objects, which are the next great things on its side of the world, forcing it to create complex and error-prone object converters in order to turn a NewUser into a User and... get the darn schniblitz!
The kicker is that the innocent victim had a contextually-valid country code. So should the original method had reduced its needs and simply had asked for what it needed, the angry monkeys would have had no "Thou Shalt Provide A User" mantra to sing and life would have been beautiful.
If you find that this whole story sounds too made-up to be true, take a closer look at your code. I bet that, if your code base has a few gray hairs and a bunch of modules, you're more than likely to have a few angry monkeys here and there.
Eek. Eek.








