Subject: Re: Locking URIs rather than Resources

From: [email-masked]
Date: Fri, 7 Jan 2000 17:34:35 -0500

>    * a LOCK token must be associated with the locked resource and URL
  > Umm?  This doesn't sound like a requirement.  At least not a
fundamental
  > one.  Feel free to explain what you mean if you think this is an
important
  > point.

  I had this as a requirement for compatability with RFC 2518.  Are you
  suggesting that lock tokens are superfluous and should be removed?

No.  Just that lock tokens are an implementation of a requirement, not
a requirement in and of themselves.  If the same can be achieved in some
other way, that's fine.  You seem to be shooting for compatibility in which
case LT are the mechanism to use.  -- I didn't actually understand the
point of your statement either.  That's fine though.  What's most important
is what you say below.

   It wasn't clear to me in general if shared locks were the default rather
   than exclusive, but it seems natural that this should be the case for
both
   name and resource locks.

I hadn't considered the possibility of name locks being exclusive.  The
need
for this wasn't one of our requirements.  We just wanted to protect a URI
from
having it's mapping change.  This was purely for the sanity of the client.

My initial vote for resource locks is that there be no default.  One must
specify what one wants.

   As far as treating name locks as a formal entity,
   that is a better way of describing what you are doing when you want a
lock
   on a URL not associated with a resource--you're locking only that PART
of
   the collection resource corresponding to that name in its set of
bindings,
   you aren't locking some resource that that name will be associated with
   later.

I'll just try harder to assimilate this view.

   I think that people who have worked with locking before understand the
   difference between locking an aggregate object and an individual item in
   that aggregate, as there are many examples of that in software today
   (locking a file vs. locking a byte range in that file, table locks vs.
row
   locks in a SQL database, etc.).  I don't think people are comfortable
with
   the idea of treating namespaces as lockable entities separate from the
   entities the names refer to, since that isn't generally done.

Actually, only Geoff's most recent proposal couched it that way.  All
others
have tended to say that a predetermined set of bindings are "protected".
The
term "locked" wasn't used... and after it was set up, it wasn't based on
namespace... just bindings.

  Once you
  agree that the set of bindings are part of the state of a collection, you
  are treating the collection resource as an aggregate that can be locked,
as
  well as one or more bindings it contains.  The model I propose is
simpler,
  in that only one kind of object WebDAV requests can refer to--the
resource,
  without treating URLs as something separate.

A good thing. URL's are just a side effect.  I forget the word Geoff used
to
use to refer to this.

  > I agree with the semantics, but I'm uncomfortable with creating a new
  > concept
  > called a "lock set".  This also rings of "implementation".
  > Hopefully this can be avoided.  Anyway...

  The lock set is just a group of locks associated with a single lock
token.
  Given that the Depth: infinity header effectively gets many locks (rather
  than one big lock) and associates them with a single token, you were
already
  doing this before, just without a name.  It just seemed to me to be
easier
  to understand if you have a term for describing what a lock token
  identifies.  This is just a terminology issue.

I am still uncomfortable speaking of sets of locks.  Also, that's not what
we had before except in one proposal that someone made (twice) but that
proposal didn't last long.  People liked the dynamic nature of this.
That's
not to say that it had to be based on namespace.  Just parentage.

Perhaps I shoudln't say this, but with the advent locking of collections,
do
we still need depth locks?  I forget why this was important and what set of
people felt it was important.  I know Jim Whitehead was one of the people
and I believed the others were document management folks that wanted to
to lock composite entities.  Anyway, I just wanted to check if we still
need them.  If so, I'd like to explicitly note this in the locking doc I'm
doing.

Re: Depth locking...

  >    An RFC 2518 LOCK
  >    request applied to a collection will work in the same way, except
that
  >    if
  >    the depth header is specified, name and resource locks will be given
  >    recursively for each contained resource.
  >
  > Hmmm.  Or perhaps just resource locks.  No, that won't work either.
  > Okay...
  > You're going to have to explain some of the
  > complications of this.  Like, are all of these resources still locked
if
  > you
  > remove the binding that put them under the influence of the original
lock
  > request?

  No.  The LOCK protocol request is a shorthand way of requesting a set of
  names and resources to lock.  Deleting one of the names or resources you
  have locked removes the locks, since you have nothing there remaining to
  lock.

The DELETE only removes the binding.  The resource may still exist and
be exposed at other URI's.  More below.

  The validity of the relationships between the set of names that are
  locked and the resources they apply to is not maintained.  Here's a
boundary
  case to illustrate the issue:

  Let's say I have resource ID 1 bound by foo.html, ID 2 bound by bar.html,
  and ID 3 bound by werf.html, all in the same collection.  Now, I issue 3
  LOCK requests on each URL, and get lock tokens T1, T2, & T3.  Now (using
a
  temporary URL) I MOVE everything around so that foo.html refers to
resource
  ID 2, bar.html refers to ID 3, and werf.html refers to ID 1.  LOCK token
T1
  still refers to foo.html and resource ID 1, even though foo.html now
refers
  to resource ID 2, and if I UNLOCK with token T1, foo.html and resource ID
1
  are unlocked.

Yucky!  A very nice clean model, but it doesn't serve the client very
well if the methods will act this way.  Letting a LT's name locks get
separated
from it's resource locks seems like a bad idea and probably serves no
purpose.
In addition, the client can't release one type of locks (name) without
releasing the
other (resource)... unless the client creates two lock sets explicitly.

  >  I have to provide token T2 to UNLOCK resource ID 1.

I think you mean you have to use T1 to unlock ID 1, but you have to use T2
to
unlock the name/binding/slot that currently maps to ID 1.

  > And does adding a resource to a depth locked collection, create a
  > resource and name lock for the newly bound resource?

  I would say that the default for this would be no, since again the
  relationships between the names and resources is not something that the
  server enforces--only clients can do that via use of locks.  Since the
  collection is locked, you would have to provide the lock token to insert
the
  new resource into the locked collection anyway.

The thinking on the list has been that they want it automatically extended
to
the children.  Folks have questioned this on occasion and the folks that
value
depth locks have always expressed a preference for the locks automatically
being extended to children.  In addition, they liked having the lock stop
applying to any child resource that leaves the locked tree.

  However, there may be some need for combining the PUT and LOCK into the
same
  request to avoid race conditions.  I can see this being an issue with a
  number of protocol requests (BIND & LOCK, etc.).  There probably needs to
be
  a way to add a lock as a part of any WebDAV request.

Perhaps folks would find this acceptable.  That is, if a client is adding
to a
locked collection, the client can specify that the lock be extended to what
it is
adding to that collection. -- Or perhaps we'd make the default to extend
any
depth locks affecting the collection into which a resource is added.  Noone
has mentioned actually wanting it NOT to be added.

  > And do name locks remain
  > if a subtree is separated from the tree where the original LOCK request
  > was submitted.

  Yes.  That is why each name in the path (logically) is locked separately,
to
  simplify the task of tracking all of these types of issues.

When stated as I did above, people have expressed a preference to having
the
inherited locks stop acting on the resources that move/delete away.  But
if it was the resource
itself that was originally locked (not via inheritance) many folks like it
to
continue to affect the resource even after movement/unbinding.

  > If you delete a locked binding, is the name lock automatically deleted?

  If you DELETE a locked resource, the resource lock is removed from the
lock
  set, leaving only the name locks.  I.e. I Lock /a/foo.html.  Then I
delete
  /a/foo.html.  I still have the name lock, so nobody else can put
something
  at /a/foo.html (I'm reserving the namespace like an LNR).
  I think this will
  be needed for doing certain types of tree manipulations as an atomic
unit.

Reserving the namespace can be a good thing.

As for unlocking the resource that was deleted... remember, DELETE just
removes a binding, and does not necessarily destroy the resource.  It may
or may not having other bindings and mappings.   I don't disagree that
this might be the right thing to do, but if we do decide to unlock that
resource, we have have to cross our fingers when we say the resource lock
is on a resource.

  > Thus we get the benefit of LNR's without having to create a pseudo
  > resource
  > there.  Presumably PROPFIND will not pretend there is a resource there
  > either.
  > This sounds very good.  It's the main positive point I see in this
  > proposal.

  Right.  This is the main goal of my proposal, to create an abstraction
that
  is general.

  >    3) the activelocks property displays all name locks active for this
  >    collection as well as all resource locks.
  >
  > BTW, Would activelocks on a collection would reveal name locks on
  > descendents
  > rather than the name locks of bindings to the collection?  Hopefully.

  Yes.  The activelocks property (as a property of the collection) should
only
  reveal state belonging to that collection.  Since the list of bindings to
  descendants is the state of the collection, activelocks would list any
locks
  on those names.

Yea!  So "LNR"s will reject PROPFIND requests just like ordinary null
resources.
Good stuff.

  >    4) the "locktype" property is used to distinguish between name and
  >    resource
  >    locks.  If locktype "resource" is specified, only the specified
  >    resource
  >    lock is granted in that lock set.  If locktype "name" is specified,
the
  >    names from root to the resource are locked, if the Depth header is
not
  >    specified.
  >
  >
  >    If the URL "/a/b/c.html" is given, negative depth values can be
  >    given to lock fractions of the path.  E.g. if Depth:0 is specified,
the
  >    name
  >    "c.html" is reserved in collection /a/b, but no other locks are
  >    granted.
  >    If
  >    Depth:-1 is specified, the name "b" in "/a" is also reserved (etc.)
  >    Only if
  >    locktype is not specified does the LOCK request behave as it point
#2
  >    (granting resource & name locks simoultaneously), basically for
  >    compatability with existing applications.
  >
  > Is all this needed? I thought the point in locking the name was to
insure
  > that
  > the locked resource remained accessable to the client at a known URI?
  > "-1"
  > doesn't achieve that and may prevent trivial implementations on top of
  > some
  > respositories.  I'm also not sure I understand the motivation (at least
  > given our
  > current capabilities) of a client locking a resource without also
locking
  > the
  > namespace.  Currently it doesn't seem helpful to lock a resource if you
  > can't
  > get at it subsequently.

  I can see the value of allowing a URL reference that is derived from a
  resource ID, like "/resources/1234" or something in some implementations
  (Oracle's implementation will have this).  Resource ID is constant
  regardless of BINDings.  I recommend adding something like this to the
  protocol.

I can see the value in that too.  It sounds like something that could
neatly
go in a separate proposal.  It doesn't impact anything else.

Still though... I have my doubts that all of the above concerning negative
depths is worthwhile. And in fact for platforms like IIS that want to use
native capabilities, I don't think they'll be albe to do anything other
than
lock all of the bindingss up to the root.

---

From: Eric Sedlar <[email-masked]>
Date: Fri, 07 Jan 2000 15:44:56 -0800

You make a bunch of comments about lock sets and Depth locks, and you don't
seem particularly comfortable with any of this stuff.  This is all coming from
Document Management requirements for compound documents.  I think the correct
solution to these issues comes from understanding that requirement.  Here is a
counterexample to your dynamic lock preference...

Let's say that I have a "book" entity that I want to manifest as a collection
resource (with some additional XML properties describing the book's state).
In the collection is a set of HTML resources corresponding to each chapter of
a book.  Let's say that this book is a programmer's guide  for a software
product, and a couple of these chapters are about "Getting Started".  Now we
add an administration manual (another collection somewhere else) and I want to
share the Getting Started (GS) info between books, so I want to move those
chapters into a third collection containing shared resources between the
manuals.  I have the following collections now:

/manuals/prguide
/manuals/common
/manuals/admin

When I started working on the programmer's guide (PG), I depth:infinity lock
the entire collection with a shared lock, to make sure nobody messes with the
chapters while I am working.  When I move the GS info out of the locked
collection I want to retain these locks, since they are still part of the
manual.

The automatic assumptions Jason proposes regarding when locks are removed in
the face of BINDs, MOVEs, etc. are not going to be correct in all cases.  If
I depth lock a collection, I have a perfectly valid example of when I want to
retain the lock when members of a collection are moved out.  There is no
recourse in this situation, since reestablishing the lock introduces a race
condition.

Therefore, I think it is better that the client (i.e. the application) have
specific control of the locking semantics, and that the server not try to do a
lot of funny stuff with guessing what the client wants.

---------

Other miscellaneous responses:

* the negative depth proposal, along with a header to allow name locking
separate from resource locking, are for the functional completeness of the
model.  The problem with locks is that you often want to get a bunch of them
at once (and have the server handle any deadlock detection issues).  Another
way to handle this is to allow a list of URLs to be LOCKed to be attached to
ANY request.

* when I refer to DELETEing a resource in my proposal earlier, I mean a DELETE
that removes the last binding, deleting the associated resource.

--Eric

---

From: Jim Davis <[email-masked]>
Date: Sun, 09 Jan 2000 09:08:13 +0100

At 03:44 PM 1/7/00 -0800, Eric Sedlar wrote:

>resource ...Let's say that this book is a programmer's guide  for a software
>product, and a couple of these chapters are about "Getting Started".  Now
... I want to move those
>chapters while I am working.  

This is a good use case, thanks for contributing it.  I think it's
reasonable to require that something like this work.  But I don't agree
that it shows a problem.  I think there are at least three ways to use
WebDAV and meet your requirements.  

1) lock the common collection with depth infinity.  Then when you move the
files, they are added to the lock. 

2) Create a temp collection, depth lock it, move the files there.  edit
them until you are ready to release the lock, then move them to the common
collection, where they will be seen by your co-workers.

3) For each file that you wish to move to common, lock a null resource in
the common collection.  then do the moves.  the formerly locked-null
resources will become locked "normal" resources.

Is at least one of these acceptable?

Note that I am talking about  WebDAV as in RFC 2518, I am not completely
sure these apply to the newer proposals for lock. 

>lot of funny stuff with guessing what the client wants.

That's a good principle in general.