Where is RAII not going to work?

Datetime:2016-08-23 00:43:01          Topic: Cassandra  DataBase  C++           Share

As I was getting ready to publish a new web application, I noticed some problems, pages marked as being CREATE when I could clearly see that they were marked as NORMAL (ready to be viewed.)

Looking into it closer, this was created by a status not being saved properly. We use Cassandra as our backend and my status was handled in a way similar to:

page->set_status(CREATE);
...
[create the page here]
...
page->set_status(NORMAL);

The logic is perfect and I could see that the status was set to NORMAL before moving on to creating the next page. However, for some pages, the database would still report the status as CREATE. Why?

The Cassandra C++ driver makes use of threads that send data to the Cassandra cluster selecting either node you have available and which is not too busy. This means the NORMAL status may end up being sent first! So the database does it right , but what does that mean for us?

Well... one main thing: We cannot set the same field to more than one value and hope that the last one is the one that sticks. The problem happens in the initialization process because we save large files (attachments) and thus the thread that is to take the CREATE and NORMAL statuses is not going to be the same one . This could also happen in normal production.

As a side effect, it means you cannot use RAII to switch to one state, then restore to another. You may still use RAII if it makes sense, but the idea is that in the end you called set_status() only once. Users of RAII are usually setting a value in the constructor and resetting it back in the destructor. With Cassandra, you cannot do that and expect the correct result!

class raii
{
public:
  raii(state s)
    : f_saved(page->get_status())
  {
    page->set_status(s);
  }

  ~raii()
  {
    page->set_status(f_saved);
  }

private:
  state f_saved;
};

As we can see, that class would call set_state() once in the constructor and once in the destructor. So it won't work because the C++ driver makes use of threads and you cannot guarantee the order in which the data will be saved in the cluster.





About List