So two weeks ago I discovered Google’s Protocol Buffers, and I have to ask, where have you been all my life?
The project I was working on requires speed and scalability, both vertically and horizontally. The component I was working on is a C++ daemon that listens for HTTP requests and returns an XML document. It needs to be able to handle tens of thousands of requests per minute as its a control process. The first version of this application was written in PHP for speed of deployment and flexibility. Now that the product is mature, its time to go through some of the code and replace the PHP code with C++ code.
The problem is fairly straight forward, but somewhat database intensive. The entire application is stateless, so each request must be processed independently. A request comes in, it is parsed, database queries are performed, decisions are made based on the request variables, and we return an XML document fragment and close the connection. Since the decisions are all based on values stored in the database, I needed a method to cache stateless information. This typically comes in the form of an individual record. Protocol buffers are perfectly suited for storing a record, and possibly its relations and accessing them.
I coupled this with memcache and a thread-safe pool of connections to the memcache server and get incredible performance out of it.
The only problem I’ve encountered with them so far involves multiple inheritance. I’ve got another base class called DatabaseRecord which all of my other classes are derived from. It contains common functions that are shared between all accesses to the database. The next logical step would be to have moved all of the actual columns into protocol buffer classes and then use multiple inheritance and use DatabaseRecord and the protocol buffer class as the base classes for my actual records. Unfortunately, it didn’t work, and I got a number of compiler errors when I tried.
So, the next best thing was to declare a couple of pure virtual member functions in DatabaseRecord and use public instance of the protocol buffer class in each specific record. The pure virtual functions are called by DatabaseRecord classes to pull data from memcache and populate the protocol buffer record. Not as clean, but still very elegant and it gave my application a huge performance boost.
If anyone is interested let me know, and I’ll put up a bit of sample code.