My first impression is that this scheme adds significant complexity,
where a simpler method would suffice. The simpler method:
- Have the a locks table which any client may access. Only one
client may hold a lock for a given path.
- At commit time, the server may check the committed paths to see if
any of them are protected by locks. Conceivably if all clients
that wanted to edit a file were "nice" and held the lock before
modifying it, then this check would not be necessary.
I talked on IRC with Ben about why the long-lived transactions were
chosen over this simpler scheme. The motivation seemed to be that
with DAV mounts, every single "auto-save" of a file would create a new
revision. With committing a revision automatically upon UNLOCK,
hopefully the number of revisions would decrease as most clients only
issue an UNLOCK when they are truly done with the file.
I think a simpler solution would be to attack this at the higher
layers: either through DAV autoversioning, or the application layer.
To fix it at the DAV lyer, you would just have the DAV layer perform a
commit for every PUT, except if that resource was locked, then perform
a commit every time a lock is release. This scheme does break the
property that every PUT is immediately seen by other clients, however
I think it is unwise to allow unversioned data to be transparently
propagated to other clients. How would the text-base work in that
case? The client would have no idea what version of a file it had
locally and thus no means for transmitting diffs to/from the server.
Alternatively this could be fixed at the application layer, but
turning off the "auto-save" feature.
-Josh
Ben Collins-Sussman wrote:
> Here's the general jist of our original locking design for libsvn_fs.
> I'm using casual language to describe it, purposely not going into too
> much detail, so that it can be easily compared to other designs. (We
> *have* done some detailed API spec'ing, which we can describe later.)
>
> Also, remember that this is not a UI discussion. For the moment,
> we're deliberately avoiding chat about how a Subversion client would
> create/destroy/discover locks.
>
> ---------------
>
> The main idea is: a user "locks" a file in the filesystem. This means
> than a new (potentially) long-lived transaction is created in the
> filesystem which represents this one locked file. There's a 1-to-1
> mapping between a locked file and a lock-txn. We keep this mapping in
> a new 'locks' table that maps a path to a txn-id.
>
> * When somebody tries to write to any path, the filesystem checks to
> see if a lock-txn already exists for it. If so, and if the writer
> owns the lock-txn, then the new data is put into the lock-txn,
> overwriting whatever was previously there. (And obviously, if the
> writer doesn't own the lock-txn, the write is rejected.)
>
> * When somebody tries to read from a non-HEAD revision, everything
> is normal. When somebody tries to read from the HEAD revision,
> the system treats locked paths specially: instead of pulling the
> file's data out of the HEAD revision, it gets pulled out of the
> appropriate lock-txn.
>
> * The lock-owner ultimately ends up "unlocking" the file, which
> causes the lock-txn to be committed. Either that, or the lock
> owner destroys the lock, which aborts the lock-txn, and all
> changes are lost.
>
> The net affect of this (from a WebDAV client's point of view) is that
> a user can LOCK a file indefinitely and do any number of PUTs to it.
> People who do checkouts of HEAD, or just GETs of the file, will always
> see the file's latest text (that is, whatever text was most recently
> PUT by the lock-owner.) If somebody else tries to do a normal
> Subversion commit which includes a change the locked file, the entire
> commit will be rejected. Ultimately the owner UNLOCKs the file and a
> new revision is created.
>
> Really, we envision at least two APIs to end the lifecycle of a
> lock-txn:
>
> 1. A call to svn_fs_unlock() will attempt to commit a single
> lock-txn and create a new revision.
>
> 2. A new svn_fs_commit_txn2() function will take a "main" txn as
> usual, but also take a list of lock-txns. It would first merge
> the lock-txns into the main txn, then merge the whole thing with
> the HEAD revision.
>
> Depending on how we design the new commit function, we might also want
> to give users the option to "hold on" to their lock-txns after the
> commit completes. (In other words, delete the temporary main txn, but
> not the lock-txns.)
>
> There's at least one annoyance with this design: operations like
> 'move' and 'delete' must verify that no locks exist for paths below
> the deleted/moved thing. This requires scanning the table of locked
> paths, or doing a 'reverse directory walk'. Actually, it may be slow
> in general to scan a locks-table -- we're talking about doing it for
> every read of a path@HEAD and every write of a path.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
>
>
--
Function reject.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu May 20 05:28:45 2004