Hey,

I have just committed all refactorings to core, library and extensions. There are a ton of changes, but the main one is related to the implementation of the BASE principles for persistence.

This specifically means that UnitOfWork now truly is a record of changes, and upon UoW.complete() these changes are sent to the EntityStore. The EntityStore, if following BASE (not mandatory), simply validates the list and stores the list of events, but does not apply it to the state. This ensures that the changes are transactionally stored and the system is now in an eventually consistent state.

If the EntityStore needs to respond to getEntityState requests, then the changes can be applied either by a background thread or when someone calls getEntityState(). Currently the application of events only happens when getEntityState() is called, but this is an implementation detail. If the EntityStore wants to it can also skip applying all events before responding to getEntityState(), which will return stale state, but with the benefit of being immediate. In large clustered solutions where it is ok that state is not 100% up to date for certain requests this will be very important for scalability and performance.

All EntityStore calls now have full metainfo about the Usecase and UnitOfWork. This means that you can specify CAP-metadata on the Usecase and the EntityStore can use this to make the decision mentioned above, for example. There are also all sorts of implementation-specific metainfo that can be supplied here, both per-usecase and per-unitofwork.

The InMemory store and JDBM are both working. There is a new Map-oriented interface you can implement which ONLY requires a String->byte[] implementation to work. InMemory and JDBM both use this, which makes the implementation trivial. This can be used to try out all sorts of map-based persistence mechanisms with very little effort.

One funny side-effect of this is that I think both the SQL and Neo4j stores (neither of which work now btw) will be much more attractive. The SQL one because it allows it to be secondary and so can store the data in a denormalized fashion, i.e. not in a format that is useful for getEntityState(), but rather for other reporting, auditing and similar purposes. For Neo4j it solves the problem that for those who are not comfortable with storing their data in Neo4j, well, they won't be, per se, as Neo4j is only *one* consumer of the events. It becomes a "throw-away" representation, and the core data is stored in event logs which can be replayed on whatever persistence solution is deemed appropriate. I think this will make it more appealing to use "esoteric" persistence mechanisms, as they don't represent the "core storage" anymore, but their specific abilities, such as graph traversal in Neo4j, can still be used by the application.

Lots more to say about all of this, but this post is long as it is. The main problems right now is that both the Neo4j and SQL entitystores are completely out of date and needs more or less a rewrite. The good news is that it will be vastly simpler to do so now with the new SPI. Any takers on that?

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to