Subject: Re: Locking URIs rather than Resources

From: [email-masked]
Date: Fri, 7 Jan 2000 15:35:58 -0500

Just forwarding Eric's response below to the dist-authoring list since I
suspect it's more relevant there and that's where the discussion was
previously...

---------------------- Forwarded by Jason Crawford/Watson/IBM on 01/07/2000
03:34 PM ---------------------------

"Eric Sedlar" <[email-masked]> on 01/07/2000 02:36:33 PM

To:   Jason Crawford/Watson/IBM@IBMUS
cc:   <[email-masked]>
Subject:  Re: Locking URIs rather than Resources

More discussion of the model I propose for LOCKs.

----- Original Message -----
From: <[email-masked]>
To: "Eric Sedlar" <[email-masked]>
Sent: Tuesday, January 04, 2000 4:52 PM
Subject: Re: Locking URIs rather than Resources

>
> Offline note.  Feel free to reply on the list if you like...
>
>    1) are the list of names in a collection logically part of the
> collection,
>    or do they live in some separate space outside the domain of
resources?
>    To me the answer must be that they are a part of the collection.
>
> I think all recent proposals agree that the binding is part of the state
of
> the collection.  You shouldn't get much debate about that.
>
>   type of object that can be identified within this model is a resource.
> You
>   are going to have (in a real system) access control on resources, and
not
> a
>   separate access control model for names.  There are too many concepts
in
> the
>   world of the web to introduce another type of object other than a
> resource.
>   Every filesystem in the world stores the list of filenames as a part of
> the
>   directory, and locks & access control on the directory affects all
names
>   within.  Let's stick with current usage unless we have compelling
reasons
> to
>   deviate.
>
>
>    2) what kind of locks are there?
>
>    IMHO, there must be two kinds of locks--name locks and resource locks.
> The
>    problem with just locking a collection resource is that it is to
>    coarse-grained--there are lots of applications that will want to just
> lock a
>    single name in a collection, and resource locking every collection in
a
> path
>    will reduce concurrency too much.  I think of this like table level
and
> row
>    level locks in a database--a lock on the collection is like a table
> level
>    lock, locking all names (rows) in that collection.  Another way to
think
> of
>    a name is like a fragment within the collection document.
>
> I agree with your taxonomy of requirements, but I don't agree that a name
> lock has
> to be a formal concept.  We have talked about URI protection in previous
> locking
> models. UP also probably filfills the same need and isn't a new kind of
> lock.
> It's just a behavior.
>
>
>
>
>    Now that we understand that, what do we do about RFC 2518 LOCK's?
(I'm
>    using a capitalized LOCK to distinguish the RFC 2518 protocol request
> from
>    name locks and resource locks).
>
>    The requirements are:
>
>    * a LOCK on must prevent the resource from being moved, for
> compatability
>    with existing applications.
> Yup.  We've seemed to settle on this.
>
>    * a LOCK on must prevent any changes to that resource (updates,
deletes,
>    etc.) if it exists
> Yup, but FWIW, most of us consider DELETE to fall in the category of
MOVE.
> It's not a modification of the resource itself.
>
>    * 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?

>
>    So, it seems like that the following solution is the right
abstraction:
>
>    1) add the notion of name and resource locks.  A name lock applies to
a
>    single level name within a collection.  A resource lock applies to the
> data
>    identified by a particular URL.  If that URL identifies a collection,
a
>    resource lock locks ALL of the names in that collection, and is
blocked
> by
>    any name lock within, and vice versa.
>
> Understood.  I'm uncomfortable speaking of name locks as a formal entity,
> but I find them as an acceptable way of explaining URI protection.  If we
> do speak of name locks, I suspect we're also going to have to mention
> things
> like them being implicitly shared rather than exclusive.

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.  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 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.  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.

>
>    2) we introduce the notion of a lock "set".  A lock set is a group of
> any
>    number of name and resource locks.
>
> 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.

>
>    Each lock set as a single associated
>    lock token.  An RFC 2518 LOCK request applied to an existing
> non-collection
>    resource will grant name locks to each name in the path from the root
   > down
>    to the bottom, and a resource lock on the identified resource, create
a
> lock
>    set from this group, and grant an identifying LOCK token.
>
> Sounds fine.  We'll have to go over details later.  So far this is
exactly
> like
> some of our other models... just explained differently.  Perhaps folks
will
> find
> this phrasing easier to approve.  :-)
>
>
>    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 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.  I have to provide token T2 to UNLOCK resource 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.

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.

> 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.
> 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.

>    A LOCK request on a URL giving a
>    nonexistent name in a existing collection will issue only name locks
on
> the
>    path elements.  If the URL minus the last path element does not refer
to
> an
>    existing collection, the LOCK request will fail.
>
> 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.
>
> Hmm.  I've been wondering.  (This is actually a question for everyone
else.
> Especially Yaron.)   Why do we even have the activelocks or lockdiscovery
> property at all?  Just so clients can figure out who has a lock
> that is preventing them from doing something?
>

It would be nice to give an error message to people saying "sorry, you
can't
modify that--it is currently locked by Geoff" or whatever, so that they
know
who is blocking them.  I think Windows does this in some cases.

> 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.

>    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.

--Eric

---

From: [email-masked]
Date: Sat, 8 Jan 2000 21:33:14 -0500

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.

Of course it sounds like you don't need to (or want to) move it out of the
locked
collection though.  You just need to add a binding from the common
collection.  You get the right result that way.  Even for
exclusive locks.

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

And if it is the last binding, whether the resource is locked or not is
probably moot.
If it isn't the last binding, then I take it you feel the resource remains
locked?