Re: claimed completion of ACTION-97 - proposal for pure-HTTP paging

* Steve Speicher <sspeiche@gmail.com> [2013-09-23 19:53-0400]
> 
> On Mon, Sep 23, 2013 at 6:27 PM, Eric Prud'hommeaux <eric@w3.org> wrote:
> 
> > * Steve Speicher <sspeiche@gmail.com> [2013-09-23 14:53-0400]
> > > Hey Eric,
> > >
> > > +1 but a question below...
> > >
> > > On Sat, Sep 21, 2013 at 9:40 PM, Eric Prud'hommeaux <eric@w3.org> wrote:
> > >
> > > > Find the <PROPOSAL/> 44 lines down.
> > > >
> > > > TimBL's comment LC-2836 proposed moving page control out of the body
> > > > of an LDPR and into headers.
> > > > <
> > https://www.w3.org/2006/02/lc-comments-tracker/55082/ldp/2836?cid=2836>
> > > >
> > > > This buys us:
> > > >   • Potential reuse outside of LDPRs.
> > > >   • Unrestricted data in an LDPR (screw case: an LDPR which includes a
> > > >     page from another LDPR).
> > > >
> > > > The first example in the LDP LC decribes how a GET on <resourceURL>
> > > > 303's (now 208½'s?) to e.g. <resourceURL>?firstPage, or OPTIONS on
> > > > <resourceURL> yields:
> > > >   Link: <resourceURL>?firstPage; rel="first"
> > > > The content of <resourceURL>?firstPage includes client data plus this
> > > > paging data:
> > > >
> > > > [[
> > > > <http://example.org/customer-relations?firstPage>
> > > >    a ldp:Page;
> > > >    ldp:pageOf <http://example.org/customer-relations>;
> > > >    ldp:nextPage <http://example.org/customer-relations?p=2>.
> > > > ]] <http://www.w3.org/TR/ldp/#ldpr-PagingIntro> (can we have an anchor
> > > >    on the <div class="example"/> elements?)
> > > >
> > > > The paging in this example is a singly-linked list split across HTTP
> > > > and the payload. We can move it all into HTTP (for the reasons above)
> > > > using link types defined in RFC5988 Web Linking:
> > > >
> > > > first      - An IRI that refers to the furthest preceding resource in a
> > > >              series of resources.
> > > > last       - An IRI that refers to the furthest following resource in a
> > > >              series of resources.
> > > > previous   - Refers to the previous resource in an ordered series of
> > > >              resources
> > > > next       - Refers to the next resource in a ordered series of
> > resources.
> > > >
> > > > The type arc can come from RFC6903 Additional Link Relation Types:
> > > > type      - Refers to a resource identifying the abstract semantic
> > > >             type of which the link's context is considered to be an
> > > >             instance.
> > > >
> > > >
> > > > <PROPOSAL>
> > > > • GETs and OPTIONS on <resourceURL> remain the same.
> > > >
> > > > • GET/HEAD on <resourceURL>?firstPage returns purely user content with:
> > > >     Link: http://www.w3.org/ns/ldp#Page; rel=type
> > > >     Link: <resourceURL>?page2; rel=next
> > > >
> > > > • Lack of a Link: rel=next means you're at the end (closed HTTP world).
> > > >
> > > > • GET/OPTIONS on "doubly-linked servers" return an addtional last linl:
> > > >   Link: <resourceURL>?page2; rel="last"
> > > >
> > >
> > > Why does this imply "doubly-linked servers" and why do you call this out
> > > and not "first"?
> >
> > My proposal is intended to cover two cases, the original expressivity
> > of the navigation data that was in the RDF payload (which I would
> > describe as being navigated like a singly-linked list) and a more
> > expressive "doubly-linked" mode which delivers both the head and tail:
> >   Link: <resourceURL>?firstPage; rel="first"
> >   Link: <resourceURL>?page2; rel="last"
> >
> > I expect that many applications will benefit from being able to skip
> > to the end, and RFC5988 already provided the vocabulary, so it seemed
> > like a pretty natural feature. I'm not a big fan of optional features,
> > but since back-traversal wasn't in the original langauge, I didn't
> > feel entitled to add it when migrating to HTTP headers. Also the
> > singly-linked server could be implemented with static content, unaware
> > of what had been appended to the end of the list, and I didn't want to
> > take away that feature. Zat make sense?
> 
> Zat does make sense, what I thought but I couldn't conclude how "last"
> implied doubly-linked (so you confirmed it doesn't, just extra features
> that RFC5988 provides)

I agree that "last" doesn't specifically require "previous" but "last"
is required to make "previous" particularly useful. This leaves three
remaining potential profiles:


=current, forward traversing system=

Today, we have a system which enables forward traversal of the pages.
With this minimal profile, the service doesn't need to maintain any
state besides that on the last page. When outgrowing or migrating from
testing to production, the initial service needs no coupling with the
later service(s); it simply statically serves a "next" pointer to a
page at another service. A client wanting to access the last page has
to traverse forwards to get there. If the client wants to traverse
backwards, it can either traverse from the start until the "next" is
the currently-viewed page or keep a local cache of the pages.


=with "last" pointers=

We can avoid most of these forward traversals by making the server
keep a "last" pointer. This enables the common case of access to the
last page, but back-traversal, e.g. to see earlier Bugs or previous
WorkOrders, still requires traversal from the first page.


=with "previous" pointers=

If we want to enable cheap back-traversal, we can make the server
serve an additional "previous" pointer. A "previous" link isn't much
good without a "last" link 'cause the client that has already
traversed to the last page has all the info it needs to cache its own
backward links.


Having all these choices means lots of code paths and increased burden
on client implementations. The additional state maintenance burden of
maintaining "previous" links as pretty trivial for a service already
maintaining "last" links. I propose two profiles, one with minimal
state maintenance (i.e. our current functionality) and one which
requires both "last" and "previous", (i.e. "doubly-linked").


=case for "last" as "last known"=

In the use case of migrating from a testing service to a
production service (without throwing away data accumulated during the
testing phase), Test has a "next" pointer to a page on Prod, which
then has "next" pointers through its pages:

  <Test/rsrc> -> 303/208½ to  <Test/rsrc>page=1
  <Test/rsrc>page=1 -> next: <Test/rsrc>page=2
  <Test/rsrc>page=2 -> next: <Prod/rsrc>page=1
  <Prod/rsrc>page=1 -> next: <Prod/rsrc>page=2
  <Prod/rsrc>page=2 has no "next".

Again, as a "doubly-linked" service:

  <T/r> -> 303/208½ to  <T/r>pg=1, last:<P/r>pg=2
  <T/r>pg=1 -> next:<T/r>pg=2, last:<P/r>pg=2
  <T/r>pg=2 -> next:<P/r>pg=1, last:<P/r>pg=2, prev:<T/r>pg=1
  <P/r>pg=1 -> next:<P/r>pg=2, last:<P/r>pg=2, prev:<T/r>pg=2
  <P/r>pg=2 -> no "next"     , last:<P/r>pg=2, prev:<P/r>pg=1

The burden is that every time Prod adds a new page, Test needs to
update its "last" pointer. We *could* say that "last" is only the last
that a server knows about. Test would never have to be updated after
the migration to Prod. Clients receiving a "last" pointer would have
to GET that page and see if it has a "next" or "last". In this sense,
"last" is skipping ahead an arbitrary amount. With this semantics,
Test would never have to be updated after it was pointed to the first
Prod page:

  <T/r> -> 303/208½ to  <T/r>pg=1, last:<P/r>pg=1
  <T/r>pg=1 -> next:<T/r>pg=2, last:<P/r>pg=1
  <T/r>pg=2 -> next:<P/r>pg=1, last:<P/r>pg=1, prev:<T/r>pg=1
  <P/r>pg=1 -> next:<P/r>pg=2, last:<P/r>pg=2, prev:<T/r>pg=2
  <P/r>pg=2 -> no "next"     , last:<P/r>pg=2, prev:<P/r>pg=1

Client traversal to the real last page looks like:

  GET/HEAD/OPTIONS <T/r>
  GET/HEAD/OPTIONS <P/r>pg=1
  GET/HEAD/OPTIONS <P/r>pg=2

where the middle GET/HEAD/OPTIONS is the protocol burden paid for not
having to maintain Test's last pointer after the migration. Cool, huh?


> - Steve Speicher
> 
> >
> >
> > >  - Steve Speicher
> > >
> > >
> > > > • GET/HEAD on <resourceURL>?page2 on "doubly-linked servers" includes
> > > >     Link: <resourceURL>?firstPage; rel=previous
> > > > </PROPOSAL>
> > > >
> > > >
> > > > I prefer these link types to others in the IANA registry:
> > > > <http://www.iana.org/assignments/link-relations/link-relations.xhtml>
> > > >
> > > > RFC6903 Additional Link Relation Types:
> > > > about      - Refers to a resource that is the subject of the link's
> > > > context.
> > > >
> > > > RFC6573 The Item and Collection Link Relations:
> > > > collection - The target IRI points to a resource which represents the
> > > >              collection resource for the context IRI.
> > > > item       - The target IRI points to a resource that is a member of
> > > >              the collection represented by the context IRI.
> > > >
> > > > POWDER:
> > > > describedBy
> > > > RFC6892 The 'describes' Link Relation Type:
> > > > describes
> > > >
> > > > RFC6906 The 'profile' Link Relation Type:
> > > > profile    - Identifying that a resource representation conforms to
> > > >              a certain profile, without affecting the non-profile
> > > >              semantics of the resource representation.
> > > > --
> > > > -ericP
> > > >
> > > >
> >
> > --
> > -ericP
> >

-- 
-ericP

Received on Tuesday, 24 September 2013 07:46:40 UTC