Wednesday, November 26, 2014

Re: Preventing race conditions when submitting forms

Sadly I have to say "good luck with that" if you're using Django, as the forms library does not support partial form data out of the box, and it's architectural design makes this difficult to achieve. This is a particularly annoying restriction of Django, especially when building REST APIs. I'm pretty sure I did a thread about this a while back, but can't seem to find it.

I have written a set of mixins that add support for this, specifically for our use case of building REST APIs, so it's compatibility with other modules is minimal (e.g. there's no django admin support), but it would give you a good base to work from. I haven't done a proper lib release for this yet, but here's a dump for reference;

(this is super alpha, with no regression tests and zero guarantees of future or even current stability)

However - the above won't help you if you're using the traditional approach of binding together your frontend and backend (e.g. handling forms with traditional <form> post, rather than using JS), mostly because it doesn't make any attempt to modify form rendering, only form processing/validation. But if someone is serious about building an application with a proper UI and conflict resolution, they (probably) would be separating their API anyway, so this would become a non-issue.

And then of course we go even deeper into the rabbit hole, if you want to listen for event changes within the UI (e.g. warn about conflicts before submit is pushed) then using the "browser pull" method is not good enough (e.g. pull every X seconds to update your local storage). Instead you'd probably want to look into websockets with a pub/sub style approach, and this is something which is absolutely not supported by Django (and probably never will be).

But if we put the "big picture" to one side and look at this practically, unless you're planning on building a complete client side JS package, then you can pretty much ignore all of the above. Many people get along just fine with not separating frontend/backend, and it is arguably more work to do it properly - which is disappointing.

This is yet another topic I'm planning on doing a longer talk about in the next few months, along with a skeleton project to get people started quicker and hopefully change attitudes in the way forms are handled. It's all working internally, just need to spend some time making it good enough for public consumption :)

Cal




On Wed, Nov 26, 2014 at 8:26 PM, Collin Anderson <cmawebsite@gmail.com> wrote:
Hi,

On websites where there's a lot of editing happening, I've been trying to minimize the number of fields available on a page for editing. Ideally only the data that changed in the UI even get sent to the server. That way there's less chance of a conflict happening in the first place.

Collin

On Tuesday, November 25, 2014 10:57:08 AM UTC-5, Paul Johnston wrote:
Hi,

Consider an e-commerce site, where Alice and Bob are both editing the product listings. Alice is improving descriptions, while Bob is updating prices. They start editing the Acme Wonder Widget at the same time. Bob finishes first and saves the product with the new price. Alice takes a bit longer to update the description, and when she finishes, she saves the product with her new description. Unfortunately, she also overwrites the price with the old price, which was not intended.

It's worth noting that the controller methods are thread-safe in themselves. They use database transactions, which make them safe in the sense that if Alice and Bob try to save at the precise same moment, it won't cause corruption. The race condition arises from Alice or Bob having stale data in their browser.

Does Django have any way to prevent these race conditions? Just rejecting the second edit with an "edit conflict" message would be a start - although some intelligent merging would be even better.

Thanks,

Paul

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/4acc27fc-917e-4c2a-8bf2-7bf58637671a%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAHKQagGF1BHKOXV69msVVRd0_u86k0KSNyPLH500PReE%3DBZUJg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment