On Jul 2, 2013, at 5:25 AM, Aristedes Maniatis <a...@ish.com.au> wrote:
> 1. There is a checkbox in the modeler at the top level for "use shared > cache". If that checkbox is ticked, then a single DataRowStore (a LRU map) is > created, shared between all contexts. If not, a separate DataRowStore is > created every time you create a new context. Yes, although if you ask me, we shouldn't support the second scenario. > 2. Each context has its own ObjectStore for keeping the actual objects (the > snapshot), and another copy of the object with any changes made in that > context. Any queries to the database fill the DataRowStore first, and then > the objects are constructed in to the ObjectStore. Yes. > 3. When a commit is made to Context A, the ObjectStore linked to context A > has a bunch of changes in it. Those changes are pushed into the DataRowStore, > and then into the database. Events are are sent to update the snapshot copy > of objects held in all other ObjectStores. Yes. Unless you turn off the events. See for instance my WOWODC presentation [1] - it has a bunch of cache-related slides. > 5. The modeler has a field called "Size of object cache". This refers to the > size of the DataRowStore map as a count of objects. Because the rows could be > 1kB or 1Mb each, it is impossible to predict how large this cache will grow > to, but it will get bigger and smaller over time. Yes. > 6. If "use shared cache" is NOT ticked, then this size is used for *each* of > the DataRowStore maps. This means that the memory usage will grow very > rapidly as you add new contexts and fill them with data. 100 contexts, each > loaded with a query that fetches the same 10Mb of data, will contain 1000Mb > of DataRowStore memory usage. Please use shared cache, as I said above. > 6. If a DataRow is not held in the DataRowStore (eg, because it was pushed > out of the map by newer data) then an event is NOT sent to the other contexts > to notify them that the object was updated when context A is committed. > Instead stale data is left in those other contexts. I think the commit itself would introduce a snapshot to the cache. So is this a reproducible case? > 7. Assuming the query cache is disabled, a query against the database will > fetch brand new objects into the DataRowStore and potentially update all the > snapshots of all ObjectStores which contain a copy of those records. Yes. > 8. A relationship join (painting.getArtist()) might find a record in the > DataRowStore and pull it into the ObjectStore without ever going back to the > database. Yes. > 9. If the query cache is hit, then the results may already be found in the > DataRowStore. If so, the the ObjectStore snapshot is updated from these > DataRows if any of those objects are not already found in the ObjectStore. You are talking about *shared* query cache? Yes, sounds about right, although the description has some room for ambiguity considering that query cache is a separate cache from object cache. > So, my questions: > > A. What is the use case of separate DataRowStores per context? It appears to > be a worse possible scenario in every case I can think of, with no upside. > The label "use shared cache" gives the impression that you are trading memory > usage for staleness of data, but that does not appear to be the case. There's none. I think we should remove it. > B. Is it an intrinsic feature of this system that a cache miss in the > DataRowStore causes no event to be sent to other ObjectStores, or is that a > bug? This means that setting the 'size of object cache' in the modeler to 0 > results in a lot of stale data. See above. Could be a bug. > C. Will a cache miss in the DataRowStore cause Cayenne to refetch that object > from the database before it then tries to commit the changes to that object. Yes. And again, per [1], my personal preference is to turn off auto-snapshot refreshing in *webapps* and primarily care about query cache. A desktop app would have different priorities of course. Andrus [1] http://www.slideshare.net/wocommunity/4-advanced-cayenne