One of my long running habits when dealing with databases has been to use transactions. Transactions simplify handling errors in complex, multi-record operations.
More recently, I’ve been using transactions to wrap external API calls that I also need to store data about. External APIs fail. For that matter, internal APIs fail too, so let’s simplify that: APIs fail. Sometimes for no good reason.
Accordingly, it’s necessary to be able to fail gracefully in the face of such circumstances. Failing gracefully includes not only rendering meaningful error messages, but also not leaving local data in an unexpected state.
Transactions provide a simple, clean way to resolve this issue too. And they seem all but indispensable when combining multi-record operations with APIs.
Lately I’ve been doing more work with NoSQL databases. They’re fantastic for certain use cases. But the near universal lack of transaction support is annoying at best.
So now the challenge is how to work around the overall issue and provide as robust an experience as possible within the local app.
This is part 5 of my ongoing series on Ruby on Rails performance. Today’s topic is a bit more complicated that some of the previous parts.
I’m going to explore an alternative to using the method 1ActiveRecord::Base.to_xml.
Before I get into that, I probably should explain why. After all, 1ActiveRecord::Base.to_xml is really easy to use. The alternative I’m going to demonstrate isn’t very easy to use.
The problem is that 1ActiveRecord::Base.to_xml can be really slow—even after making the optimizations I’ve explored in the previous parts to this series. For fairly simple AR objects, this won’t be a problem. However, when you have a deep object hierarchy and need substantial portions of it to be included in the XML response, it becomes a problem.
One instance where I encountered this was a nested has_many tree. That is, the object tree looks something like this:
ParentObject has_many ChildObjects
Each ChildObject has_many OtherObjects
The XML output is often 100k or more, and representing a few dozen or more total objects.
in ruby’s CGI::Session module, sessions are stored as a block of seeming junk, like this: “BMZWRlcm1hbiBCb25kaW5nIENvb”. it’s actually an encoded format which is all well and fine until you need to read something out of it for debugging purposes.
if you are using rails’ ActiveRecordStore, the contents of a session can be read fairly simply. since this relies on an AR model called Session, which your app most likely doesn’t have, we’ll create that too.
so, fire up 1script/console and input the following: