Skip to content
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

MultipleObjectsReturned at / get() returned more than one User -- it returned 2! Lookup parameters were {'facebook_id': u'100000902133058'} #42

Closed
Morpho opened this issue Nov 25, 2011 · 4 comments

Comments

@Morpho
Copy link

Morpho commented Nov 25, 2011

Hi!
Lately I often get errors like the one mentioned above. It seems like a race condition. When there is a very busy facebook app with many hundred requests per minute the fandjango's "User" model has more than one dataset of the same user. And following requests fail.

'''
MultipleObjectsReturned at /

get() returned more than one User -- it returned 2! Lookup parameters were {'facebook_id': u'100000902133058'}

Request Method: POST
Django Version: 1.3.1
Exception Type: MultipleObjectsReturned
Exception Value:

get() returned more than one User -- it returned 2! Lookup parameters were {'facebook_id': u'100000902133058'}
'''

Anybody else noticed that?

@jgorset
Copy link
Owner

jgorset commented Nov 28, 2011

I've noticed this behavior in particularly popular applications, too, but I'm not sure how we might mitigate it - do you have any ideas?

@Morpho
Copy link
Author

Morpho commented Nov 28, 2011

Ok, so the problem is between https://github.com/jgorset/fandjango/blob/master/fandjango/middleware.py#L70 , https://github.com/jgorset/fandjango/blob/master/fandjango/middleware.py#L78 and https://github.com/jgorset/fandjango/blob/master/fandjango/middleware.py#L80

On line 70 there is checked if the user already exists in the database. If not, on line 80 he will be created. But on line 78 there is a facebook API call which is comparatively slow. During this api call there can be other requests to the webapp which won't find a current user in the database on line 70 and so in the end there will be more than one dataset of one equal user in the database.

I think this should be enforced on database level, so "User.facebook_id" should be unique=True. Then in middleware.py on line 80 it should be catched the IntegrityError and when it's raised it should be checked if facebook_id is set. If not its probably an api exception. If yes, the "User" model should be queried again for the respective facebook_id.

So in my opinion it would be better to replace line 69 to 110 with something like that: http://dpaste.com/662645/ (untested). But it probably can be done a lot better than that.

@jgorset
Copy link
Owner

jgorset commented Nov 28, 2011

Spot on, thanks! I've fixed this race condition in bc13a21, and will backport it as time permits.

@Morpho
Copy link
Author

Morpho commented Nov 28, 2011

Love it! V4 is already great!

@jgorset jgorset closed this as completed Dec 16, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants