[Pmwiki-users] Re: Re: PmWikiDraw and multiple editors?

Patrick R. Michaud pmichaud
Fri Dec 17 08:45:09 CST 2004

On Fri, Dec 17, 2004 at 07:18:44AM +0000, Ciaran wrote:
> > Well, I think we basically only need something in pmwiki that returns a
> > timestamp that says when a file was 'last modified'. This can then be used
> > to determine if someone else has saved the drawing while you were editing
> > it. If no one else has edited it, pmwikidraw can go ahead and upload the
> > file.
> Rather than modify PmWiki to provide timestamps, Could I not get away
> with adding a Drawing 'Iteration/Change No./Revision Id' to the
> drawing file.  Which is automatically incremented each time a drawing
> is saved ? 

You can use revision numbers in the files, to do this, but timestamps
are *much* easier to work with than serialized numbers, since you don't 
have to worry about incrementing them, especially when there's the
possibility of several people modifying the same drawing.  Plus timestamps
provide useful information to boot.  Just be sure to use unix/posix-style 
times that count the number of seconds since Jan 1 1970 (i.e., don't try 
to compare "mm/dd/yyyy HH:MM" formatted times).

Here's the sequence:

1.  The user clicks on an edit drawing link and DRAW starts
2.  DRAW downloads the drawing and notes the drawing's time ("basetime")
3.  The user modifies the drawing and presses save

>From here,  the checking for a newer version can be done either by
the client or the server.  Since your steps had the client doing the
work, I'll use that here (and point out the race condition that develops):

4.  The client re-downloads the drawing from the server and notes its
5.  If the drawing's time is not the same as the basetime, then the drawing
    has been changed since the user started editing it.
    5a.  DRAW displays the new drawing in a panel
    5b.  DRAW updates its basetime to the time of the new drawing
    5c.  DRAW informs the user that the drawing changed while 
         they were modifying it
    5d.  Go back to step 3 above
6.  Otherwise, the user was working from the latest version of the
    drawing, so DRAW sends the new drawing to the server.

Note that this works even if there are three or more people editing
the same drawing -- anytime someone submits a drawing that is based on
an outdate version, they get the message and the chance to fix things
before resubmitting.

As mentioned above, having the client check the timestamps does 
introduce a race condition, however -- between the time that the client
re-downloads the drawing to check the timestamp (step 4) and sends the
updated drawing to the server (step 6), someone else could've submitted
a drawing that is then overwritten.  This is why it's better to have
the server manage the updates -- it can make sure that steps 4-6 happen
as a complete block without interference from other processes.  
For the server, 4-6 would look like:

4.  DRAW sends the updated drawing and its basetime to the server.
5.  The server checks the timestamp of the current drawing against the
    basetime sent by DRAW.  If the timestamp is not the same as the 
    basetime, then the drawing changed while the client was editing it, and 
    5a.  The server sends a message back to DRAW indicating
         the drawing changed
    5b.  DRAW downloads the latest version of the drawing from the
         server and notes the time as its new basetime
    5c.  DRAW informs the user that the drawing changed while 
         they were modifying it
    5d.  Go back to step 3 above
6.  Otherwise, the server stores the new drawing and all is well.

> one of my primary goals:  to have a drop and run PmWikiDraw, no
> modifications to PmWiki required (other than including the relevant
> script) .... Pm May well have some ideas about this [hopefully]

Well, one can always provide a custom function in a cookbook recipe
that handles the uploading and versioning of drawing files without
having to modify PmWiki's upload routines.  Thus instead of 
"?action=postupload" one would define a "?action=postdrawing" that
does all of the timestamp checking and sending results back to
DRAW as outlined in steps 4-6 above.  This wouldn't require any
changes to PmWiki or cause any interference.  :-)

Some other notes:

> > The extra mechanisms that'd be needed in PmWiki here are:
> > * Retrieve timestamp of an uploaded file => requires adding an action

This could be done via an action, but most webservers send the
last-modified date of the file via an HTTP header when the file is
requested.  Just use that.

> > * Be able to create a lock with an automatic timeout => requires adding a
> >   modified upload mechanism that only uploads if so allowed by the lock


> > > The best I hope to offer is the version history, which would enable a
> > > user to see there were multiple changes made.
> > 
> > Eh.. how could you detect this?

In most cases it's not necessary for the user to know how many changes
were made -- they just need to know that the drawing changed and
what the "current" version of the drawing looks like.

> > Time/effort is a problem of course... my suggestion is that we initially
> > just discuss what we'd like, possibly specifying different solutions such
> > as:
> > * Version history
> We will get this, most of the code is in place for this, I just
> haven't gotten around to it, in a similar fashion to page history. 
> The user will see a 'list' of all the previous drawings that have been
> saved, and have a mechanism to 'restore' that drawing.

That's gonna be a trick.  I guess it would help if we had versioned uploads,
which I know has been an oft-requested feature.  We might be able to
incorporate that into PmWiki.

> > * Detection of multiple editing
> ??

As pointed out above -- multiple editing works basically the same as just
two editors if the code is done correctly.

> > Btw... would it be possible to use a wiki page as the source of a drawing?
> > That way maybe we could take advantage of existing solutions?
> Not really no, it could do I guess but that would rather break the
> current implementation as it would have to extract the file from the
> page and write it back, they're not wonderfully nice to look at, and
> they cannot just be merged in the same way as blocks of text as the
> drawing expects a certain structure :) Sorry

"Extracting the file from the page" is extremely easy, just use 
?action=source.  Writing it back is also easy -- it's just an HTTP POST.
But yes, merging the pages in the graphical sense isn't easy, but
we're not after that (yet).  What storing the drawings as wiki pages
*would* give you is an automatic version history of stored drawings,
which could be easily retrieved when I implement PITS:00220
(view previous versions of a page).


More information about the pmwiki-users mailing list