-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Might indicate a bad software design" #743
Comments
@mecheverri This is interesting. Is there a |
I added some logging to better understand what is happening. It appears that within a request, there aren't any calls to Fortunately, on the chance that this exception might result from a race condition, I tried catching the exception and retrying the tasklet, and that seems to work. |
Okay, that's helpful. Does your logging give you any insight into what calls are happening in a particular request context? I'm not entirely sure how to reproduce this. Any pointers you could give would be very helpful. |
We have a high volume of requests and this appears to occur at random, which suggested the race condition theory. It occurs infrequently enough that I'm not able to identify a pattern regarding its cause. I have seen this so far with two different stack traces. |
Race condition is certainly a possibility. The resource that would have that condition is attached to the context, which shouldn't be shared across threads, and should generally be created per request. Would your code that creates the context be something you could share? |
I have run into this while trying to finish porting a fairly large python 2.7 appengine project to python 3.x. The following was with python 2.7.18 and python-ndb 1.11.2. I've been able to reproduce this consistently in a test case, using the _InProcessGlobalCache. I haven't tested yet with newer versions yet. from google.cloud import ndb
client = ndb.Client("test")
class Foo(ndb.Model):
a = ndb.StringProperty()
with client.context(global_cache=ndb.global_cache._InProcessGlobalCache()):
print(ndb.get_context().global_cache.cache)
# => {}
ent = Foo(a="Foo")
ent.put()
print(ndb.get_context().global_cache.cache)
# => {}
ent.put()
print(ndb.get_context().global_cache.cache)
# => {'NDB30\n\x06\x12\x04test\x12\x07\n\x03Foo\x10\x01': ('', 1675475589.391862)}
# ndb.get_context().global_cache.clear()
ndb.get_context().cache.clear()
try:
ndb.get_multi([ent.key, ent.key])
# => RuntimeError("Key has already been set in this batch: ...
finally:
print(ndb.get_context().global_cache.cache)
# {'NDB30\n\x06\x12\x04test\x12\x07\n\x03Foo\x10\x01': ('\n\x11\n\x06\x12\x04test\x12\x07\n\x03Foo\x10\x01\x1a\x0b\n\x01a\x12\x06\x8a\x01\x03Foo', None)} |
@chrisrossi any updates on this issue? |
I don't work here anymore. |
I think the issue here is we are creating a new lock on every get of a key. So for instance if I do something like this:
The first |
We are having load of these error too, after upgrading from version 1.9.0 to 2.2.2 |
@anoteboom what I ended up doing was to use two patches: We have these patches up on production for 3 months and we haven't found any bugs due to this. We were also able to fix all the cases where there were duplicate writes of the same entities using the error log
|
@usmanmani1122 Thank you for that patchfile. This triggers me to look into this again. I'll share my experience |
Confirmed! @usmanmani1122 your patch fixes this for me too. Thank you! |
There is a bit of code that reads:
Ok, we're letting you know. We have Python 3.9 code running in Appengine and are seeing "Key has already been set in this batch" often enough that I felt compelled to check this issue.
The expression in our code that triggers this is
ndb.get_multi(event.guestlists)
and the stack trace below that isI tried calling
ndb.get_multi()
, explicitly passing in duplicate keys, and it didn't trigger this issue.The text was updated successfully, but these errors were encountered: