• Advisory locking microapp

  last modified October 8, 2007 by ianb

Easy proposal

Locking would be nice.  But it's kind of hard.  It's also an applicable though less problematic issue in other applications, like TaskTracker (two people editing the same task item).

A simple microapp could do "advisory locks".  These locks don't actually keep anyone from doing anything, but they do keep track of who claims to be editing a particular resource, and warn other users.

I envision this working by including a script from the microapp, i.e., <script src="/locker/locker.js"></script>, on any edit screens.  This script will contact the locking microapp (simple JSON interface) and regularly ping that service to say "This user is still editing the page".  It will have an onunload handler to unlock the page, and also some kind of timeout.  If someone else edits the page, then there will be some kind of strong warning about the other person editing this page.

For someone who takes up this task, I expect it to be a fairly small task (if you understand this outline -- I think there are also hard ways to do this, so if this seems hard ask me because I think you might be overcomplicating the implementation -- Ian).

Counter-proposal

The "right" way to do this would probably be some kind of optimistic locking.  In this model, when you load the edit page the version of the page you edited is kept in a hidden field.  When you submit the page the backend checks that version hasn't changed.  If it has changed, that means that someone else has saved the page since you loaded the edit page, and if you submitted you'd clobber that page.

I think the proper UI in the case of this conflict would be to give the user a normal edit form, but with the newest information (and the user's changes removed).  Then show a diff from the version the user started editing, and what they tried to submit.  This shows the user what they have to reapply to the new content in order to keep their changes.  (The justification here is that it's easier for the user to reapply their own edits than to reapply whatever edits happened concurrently from another user).

This doesn't necessarily invalidate the usefulness of the more modest who's-editing tracker described above.  This resolves cases when content can be clobbered, but it is often useful to avoid clobbering content anyway.

It is possible that an automatic merge could work.  If you can normalize all the pages and come up with a simple diff (not what our diff does, but a more formal diff probably based on paragraphs), then you could try a 3-way merge with that, and only present the edit form if the 3-way merge fails.  Unlike code diffs, lines aren't an appropriate level of diffing, and the WYSIWYG editor can easily put in insignificant changes, so turning the HTML into some canonical form is essential.