Friday, December 31, 2021

Re: Eliminating inter-request race conditions

Hello,

Am 31.12.21 um 11:31 schrieb Nick Farrell:
> Correct. To be clear, I am not advocating this behaviour by default, but making it as seamless as possible to enable when required, rather than needing to attempt to hand-roll safe locking semantics each time it's needed.

Thanks for the clarification! It just confused me a bit because this approach seems to be complementary (or even barely related) to the other aspects.

> Certainly there is increased complexity. For the websites I am involved in (primarily health-related ones), if I don't end up providing a django-based solution, product owners end up demanding a SPA-based solution or similar, with the even-greater complexity to the development stack, not to mention testing.

Ahh, a very good point! :-)
But still I wonder if client-side validation and feedback should be optional? That is, if I had to do this myself, I'd hope to find a solution first that works 100 % without client-side effects. This would also help a lot with correctness and testing. Then I'd put all eye candy on top, but keeping it strictly optional.

> if request.method == 'POST':
> form = SomeForm(request.POST, initial=init)
> ...
>
> Note the `initial` parameter: It is used just as it is in the GET request. This allows you to use `form.changed_data` and `form.has_changed()` in form validation.
>
> But where does "init" come from? How can you know what version of the model instance was shown to the user when the form was rendered?

Hmmm. Yes, I see your point...

> There are only two ways I can see of to achieve this: use a full-blown "rowversion" CAS pattern, where there is a dedicated monotonic column on each table which automatically increases with each update, or the method I propose/use, where the original form values are provided via the user agent when the form is POSTed.

Then this would have to be temper-proof, wouldn't it?
(e.g. using https://itsdangerous.palletsprojects.com )

It might even be possible to serialize the entire state of the object into a single hidden field and sign it on GET, then check the signature and deserialize on POST. Or maybe, depending on the exact requirements, even the checksum of the old state would be enough in order to detect that something changed between the old version of the model (as it was when the user started editing it) and the current version (at the time the POST request arrives). This would roughly correspond to a version number without requiring an explicit field on the model.

> Gute Rutsch.

Danke gleichfalls! :-)
Thanks, the same to you!

Best regards,
Carsten

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e42bba72-f122-6223-c517-75a8f74bf222%40cafu.de.

No comments:

Post a Comment