Best way to force a new object read into the session cache

181 views
Skip to first unread message

Nephele Entity

unread,
Jan 9, 2013, 1:54:54 PM1/9/13
to objectify...@googlegroups.com
Sorry for the repost here..

Jeff

What is the best/cheapest way to "force" a fetch from the datastore / global cache in a thread?

For example doing a ofy().clear() prior to the get() operation, or is it starting a transaction with a worker that just does a read operation and returns the object as a reply. May be starting a transaction with a worker that does a read including transactionless() and returns that object.

What are the costs and pros/cons of each approach?

Thx

Alex

unread,
Jan 10, 2013, 1:17:06 AM1/10/13
to objectify...@googlegroups.com
What's the use case?
If you must have the most up-to-date state, then use a transaction, which will go all the way to the datastore.
If slightly stale data doesn't matter, then transactionless would be fine - which would either grab it from the thread-local cache if you've read it once already in that thread, or memcache (if enabled for that entity type) and has been read once already (though this will be entity data, and not a POJO unlike the thread-local cache), or to the datastore if it hasn't been read in at all yet. In the latter case, it would then save it into memcache for future use (again, assuming you have it enabled for that entity type).
Though this sounds rather like premature optimisation...

I'm fairly sure my understanding of it is like that, lol.


Alex.

Mat Jaggard

unread,
Jan 10, 2013, 3:39:39 AM1/10/13
to objectify...@googlegroups.com
You only need to worry about getting the most up-to-date version of an entity in the following situation.
1. You fetch an entity in your request.
2. You put the entity in *different* request.
3. You fetch the entity again in the *same* request as you did in step 1.

This seems like a fairly unlikely scenario, but if this is the case, you have 3 options. Two have been mentioned and the 3rd is a little unorthodox.

1. Clear the local session using ofy.clear();
2. Use a transaction to fetch your entity.
3. Use ofy.getSession().add(key, null); to clear the item from the local session.

Option 1 will also clear any other entities from the session which could cost you a few memcache operations (there's the possibility of a datastore operation too, but that's really unlikely)
Option 2 will prevent the entity from being put into the session, which means that if you use it later you'll have to do a fetch from the datastore.
Option 3 will remove that one entity from the session cache.

Mat.

Nephele Entity

unread,
Jan 10, 2013, 10:21:12 PM1/10/13
to objectify...@googlegroups.com
Matt

Thx. This helps a lot. The scenario you outline below 1-3 is exactly my situation.

My app has stretched objectify's caching mechanism in the past, so being careful about how I do the conversion. My testing on v4 is good so far. 

One question about the per thread session cache, if I am understanding correctly. Im not sure if the app servers have thread pools which are reused for requests. Did you think about the condition where a thread is reused and as a consequence a request accessing ofy().load().. is starting with a cache of stale values. Is clean up of this part of the filter processing?

Thanks again..

\n

Mat Jaggard

unread,
Jan 11, 2013, 4:05:56 AM1/11/13
to objectify...@googlegroups.com
If they do share threads between requests at all (and I wouldn't be sure either way) the ObjectifyFilter will deal with any potential issues of left over instances.

Jeff Schnitzer

unread,
Jan 13, 2013, 11:19:16 AM1/13/13
to objectify...@googlegroups.com
Mat is right - you need to have the ObjectifyFilter installed.

GAE is a forked version of Jetty. Requests are serviced by a thread
pool and Objectify holds the session cache in a thread local. You
must install the ObjectifyFilter in order to isolate requests.

Nephele, can you elaborate a bit on what you are trying to do? In
99.9% of applications, there's no reason to bust the session cache -
each request sees a consistent view of the datastore, and the only way
to guarantee correct data is to execute a transaction. It sounds like
you have some kind of long-running request that needs to periodically
refresh data from the datastore directly, which is a bit unusual on
GAE.

Is this a normal request, or is this a long-running task or backend?

Jeff
Reply all
Reply to author
Forward
0 new messages