For each field to be updated, send what the user changed it to and what the user started from (likely the cached value). Only send fields that were presented to the user to be updated (and identifying information, of course). But you may want to send fields shown to the user that the user chose not to make any changes to.

Then the service can decide what makes sense to do with a change request. I find two key aspects to making such decisions: Merging changes to different fields and merging changes to the same field.

In a lot of cases, me changing one field ("author", for example) when some other user changed some other field ("title", for example) should cause no conflict. Just apply both changes.

In rarer cases, you might want to enforce fields being updated as a group. You might not want to allow me to change the price at the same time as somebody else changes the "qualifies for free shipping" flag, for example. But I tend to think these cases are rarer than a lot of software designers tend to think.

I find it annoying, for example, that bugzilla refuses to merge my changes with somebody else's when I mark the bug as "resolved" at the same time as my PM bulk updates some project parameters like target milestone or release date. I'd rather have my changes merged and just be notified so I can resolve any merge conflicts with another updated when needed.

If you have a rare case of fields whose updates should be grouped, then it might become important to send the fields shown to the user that the user chose not to update. In fact, this is one general, conservative method for determining when field updates should be grouped. If I update the price from a form that doesn't even show the "qualifies for free shipping" flag, then surely the value of that flag shouldn't matter as far as my update is concerned, even if the value of that flag changed while I was making my update.

Second, for each field, apply the differences to that field. For large text fields this problem boils down to the classic text merge that is done by revision control systems such as git. If I make a change that only touches the 2nd paragraph while your change only touches the 4th paragraph, both changes can be applied w/o conflict rather easily. Though, web-based text entries tend to not be "line-based" and so traditional "diff" and "merge" approaches usually take some work to adapt while avoiding potentially large CPU resource consumption.

For other types of fields, other "merge" methods might be appropriate. For example, at PerlMonks, most of the numeric fields that get updated by user activity are counts so my updating a node's reputation from 4 to 5 (because I upvoted it) at the same time as you update it from 4 to 5 (by upvoting also) should result in the reputation being set to 6. The updates are viewed as increment / decrement operations and can be silently combined.

But the most common case is to just apply the update to the field, overwriting the previous update. The first user usually can't tell that the second update didn't happen right after their update (by a user who saw the first update) rather than "at the same time" (by a user who didn't see the first update).

Implicit in this advice is that you don't do the "worst case" type of update (like PerlMonk's original node cache and Ruby's Active Record chose to) and send as the update "the entire record/object after the user's changes" and then "save" that record/object whole. That easily leads to me adding something trivial and blowing away any number of important changes (even my own changes because I later made a update of something trivial from a stale web page).

But I also think you should almost always avoid the other end of the spectrum where you note that something trivial changed while I was doing my editing and therefore refuse to accept my changes. Making it trivial for me to, after reviewing the changes I had missed, just reapply my original changes, makes this end of the spectrum less horrid, but it still is too cautious, IMHO. You'll get people losing significant contributions because they didn't notice the conflict notification quickly enough and getting annoyed when forced to jump through this extra hoop over trivia.

The most conservative I would usually go would be to apply my updates that might be in conflict and give me a notice of the potential conflict and let me apply more updates in the rare case when such are warranted.

In summary, the common case is pretty simple. If the current value matches the user's "starting value" (before their edit), then just updated the field with their edited value. If starting values don't match, you probably update anyway (but only if the starting and ending values are different) but might instead do a "merge" update or notify the user that their update overwrote UserX's change of "$field" from "$old" to "$new".

Logs of recent changes can be immensely helpful in such systems.

- tye        


In reply to Re: How to deal with data race issues with Perl? (send pre and post) by tye
in thread How to deal with data race issues with Perl? by halfbaked

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.