ThreadLocal issue

139 views
Skip to first unread message

Salomon Brys

unread,
Mar 5, 2013, 1:54:03 PM3/5/13
to objectify...@googlegroups.com
So, lately, I have noticed some really inconsistent behavior in Objectify.
Sometimes my entities would be fetched modified, and sometimes, event several minutes after modification, I kept getting an unmodified version.
I checked and here is the problem : Appengine now recycles it's thread, meaning that 2 requests can be done on the same thread sequentially since the thread is not recreated anymore. Maybe it's not new and maybe they changed something else, but the result is that ThreadLocal is NOT local to a REQUEST anymore. It's local to a THREAD and re-used across requests.
(BTW, yes I have <threadsafe>true</threadsafe> in appengine-web.xml)
This is really problematic if you have multiple app engine instances running due to the session cache that is always reused and never considered invalid (and therefore de-synchronized among instances).
I found the problem when I noticed that I kept getting the same objectify object on each of my instances in production (not in development).
In sources, the problem is that, since it's the same thread doing multiple requests sequentially, ObjectifyService.STACK is not renewed, and it's always the same objectify object with the same session cache that is used.

So I used a very simple fix : in AsyncCacheFilter, line 72, I added ObjectifyService.reset();
And that solved the problem since ObjectifyService.STACK is now cleared at the end of each request.

I think that this fix should be on main sources. However, this fix makes AsyncCacheFilter mandatory EVEN for apps that do not use objectify global cache.


Bien cordialement,
Salomon BRYS


Avatar Salomon BrysSalomon BRYS | Architecte Logiciel | Chief Geek Officer
Kick Your App
80 Rue des Haies - 75020 - Paris, France
+33 9 72 37 17 24 | +33 6 83 54 55 96 
sal...@kickyourapp.com
LinkedinLogo Kick Your App

Jeff Schnitzer

unread,
Mar 8, 2013, 5:34:48 PM3/8/13
to objectify...@googlegroups.com
What version are you on?

ThreadLocals have always been thread-specific and not request-specific. Without going through the version history, I can say only this:  ObjectifyFilter does reset the stack at the end of the request, and it is mandatory as stated in the docs.

Jeff


--
You received this message because you are subscribed to the Google Groups "objectify-appengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to objectify-appen...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jon Sawyer

unread,
Mar 9, 2013, 12:36:11 AM3/9/13
to objectify...@googlegroups.com, je...@infohazard.org
Jeff,

I wonder if it would be a good idea for Objectify to fail fast when ObjectifyFilter is not present, as in throw an exception or something. That's a problem I had as well (discussed in a separate thread). Granted, it was developer oversight, but the framework could save forgetful developers like me a fair bit of time this way.

Jon
To unsubscribe from this group and stop receiving emails from it, send an email to objectify-appengine+unsub...@googlegroups.com.

Jeff Schnitzer

unread,
Mar 9, 2013, 12:56:09 AM3/9/13
to objectify...@googlegroups.com
I've been thinking about that, but there are times (such as using the remote api) when you don't want it.  Maybe if Objectify just logs a warning that can be squelched specifically.

Jeff


To unsubscribe from this group and stop receiving emails from it, send an email to objectify-appen...@googlegroups.com.

Nicholas Okunew

unread,
Mar 9, 2013, 7:47:08 PM3/9/13
to objectify...@googlegroups.com
Perhaps a NoOp filter is required explicitly if you don't want to register the standard filter?

Salomon Brys

unread,
Apr 12, 2013, 4:06:55 AM4/12/13
to objectify...@googlegroups.com
(Sorry, somehow, this mail skipped my inbox)
I'm using the last version of Appengine and the last version of Objectify's git.

Without my "fix", ObjectifyFilter is NOT reset. I don't know why...


Bien cordialement,
Salomon BRYS


Avatar Salomon BrysSalomon BRYS | Architecte Logiciel | Chief Geek Officer
Kick Your App
80 Rue des Haies - 75020 - Paris, France
+33 9 72 37 17 24 | +33 6 83 54 55 96 
sal...@kickyourapp.com
LinkedinLogo Kick Your App


Jeff Schnitzer

unread,
Apr 12, 2013, 10:56:04 AM4/12/13
to objectify...@googlegroups.com
I'm confused.

AsyncCacheFilter is used if you use the CachingDatastoreService without Objectify. If you are using AsyncCacheFilter, you shouldn't use ObjectifyService anywhere in your code.

If you want to use ObjectifyService, install the ObjectifyFilter (which itself extends AsyncCacheFilter). Then the stack will be managed for you.

It's one filter or the other.

Jeff
Reply all
Reply to author
Forward
0 new messages