Hi All, We just had the discussion regarding throwing exceptions in the Cassandra Persistence Manager API. In line with this discussion we also need to look at our CRUD APIs. A simple example is a CRUD interface on oAuth service consumers. Currently, this API consists of 4 methods:
OAuthServiceConsumer get(String consumerKey); void add(OAuthServiceConsumer consumer); void remove(OAuthServiceConsumer consumer); void update(OAuthServiceConsumer consumer); Now one important problem with this API definition is that it is kind of 'impossible' to implement properly in Cassandra. Cassandra does not differentiate between add and update. It only supports a setValue method, which creates the value if it didn't exist yet and updates the existing value if it did. An add method that only adds the consumer if it doesn't exist yet cannot be implemented, as Cassandra does not support locking (out of the box). Of course, you could still use the if (!exists(A)) add(A) approach and this will, in many cases, do the job. However, there is no guarantee; another consumer with the same key could have been added in the meantime and this construction would just overwrite it, which is not what the API promised to do. So since the CRUD API for consumers is supposed to be a generic API, suited to be implemented by several storages, I don't think this API definition is proper for the Cassandra case. add and update should be merged into a single method and if a developer wants to do stuff like if(exists(A)) add(A), he still can. Another issue is that in Cassandra you cannot tell when a remove() did actually remove a row, or that it didn't have any effect since the row to be removed didn't exist. Hence, the removeConsumer method should not differentiate between these two cases. Still the invoker can use if (exists(A)) constructions if he really needs it, but the API should not define behavior that cannot be possibly implemented by certain storage implementations. Now this is all true from a Cassandra perspective. But if I would create a relational database implementation, I would have a different opinion. One of the reasons to choose for a relational database would be its strong consistent behavior, transactions support and locking support. But with the API above I cannot expose all this strength. In the implementation of add(consumer) I could have set a lock on the table and ensure that it doesn't exist yet, before creating it. This makes sense, as it is possible that two different users are trying to add different consumers simultaneously, but coincidently with the same key. I could use locking to let the first add succeed and notify the second user that a consumer with this key already exists, where in Cassandra the first user would just have 'bad luck'. So I would feel that this API definition is too limited and would suggest separate add and update methods. Maybe this proves once again that our conclusion as mentioned on http://www.amdatu.org/confluence/display/Amdatu/Persistence was correct; there is no such thing as a generic persistence API, suitable for all storages. Still, this is what we are trying to do with our 'StorageProvider' interfaces. So again, what do you think? Regards, Ivo GX Software | Ivo Ladage-van Doorn | Product Architect | Wijchenseweg 111 | 6538 SW Nijmegen | The Netherlands | T +31(0)24 - 388 82 61 | F +31(0)24 - 388 86 21 | [email protected]<mailto:[email protected]> | www.gxsoftware.com<http://www.gxsoftware.com> | twitter.com/GXSoftware<http://twitter.com/GXSoftware>
_______________________________________________ Amdatu-developers mailing list [email protected] http://lists.amdatu.org/mailman/listinfo/amdatu-developers

