fhwang.net

Lafcadio 0.9.5: Mending mock transactions, considering continuations

Today’s release of Lafcadio, 0.9.5, is a small one, but it fixes some interesting bugs. I added mock transactions in March, and since then Brian Marick has been really stress-testing it and submitting some superbly detailed bug reports of how the mock transactions aren’t perfectly mimicking transactions in MySQL and Postgres.

For example, 0.9.4 mock transactions would fail if you committed a row and then tried to retrieve that row without leaving the transaction:

Lafcadio::ObjectStore.get_object_store.transaction {
  original = TestUser.new('name' => 'fred', 'password' => 'password')
  original.commit
  retrieved = TestUser.get('fred', :name)[0]
  assert_not_nil(retrieved)
}

To fix that, I had to seriously rejigger the transactional internals. Now Lafcadio clones the state of the ObjectStore (mock or otherwise) when a transaction starts, executes the transaction on that cloned state, and then reassigns some instance variables to use the new state if the transaction is committed. Dag. Transactions are hard, yo.

In the middle of that, it occurred to me that this time-machine sort of behavior was reminiscent of exceptions, and could perhaps even be done with continuations. I’ve been really into the idea of continuations ever since Jim Weirich gave a great workshop on the subject at last year’s RubyConf, so maybe I’ll implement the mock transactions with continuations one day.

But it’s worth noting that Jim’s workshop included a part where we paired up and tried to implement exceptions using continuations, and my partner and I did not get very far. In the case of this Lafcadio release, I just implemented it with more instance variables and a bunch of custom #clone methods. Part of me wonders if continuations are propeller-beanie territory: Theoretically interesting, sure, but too difficult to be useful in a long-term sense. In particular, I’d worry about somebody else digging into Lafcadio, hoping to write a patch, and getting discouraged by all the obscure magicks going on inside. But then, only a few years ago I might’ve said the same about method_missing, or Module#included, or, heck, redefining Kernel#require—and I’m loving all those techniques today. So, who knows. In the meantime, enjoy this non-continuation-based release.

blog comments powered by Disqus
Tagged: ruby

« Previous post

Next post »