Subject: Re: [netconf] restconf collections

From: Qin Wu <[email-masked]>
Date: Wed, 30 Sep 2020 01:11:57 +0000

Hi, Robert:
-----邮件原件-----
发件人: netconf [mailto:[email-masked]] 代表 Robert Varga
发送时间: 2020年9月30日 7:05
收件人: Kent Watsen <[email-masked]>; Andy Bierman <[email-masked]>
抄送: [email-masked]
主题: Re: [netconf] restconf collections

On 26/09/2020 20:57, Kent Watsen wrote:
>> There are 3 completely different approaches:
>>
>>   1) stateless
>>   2) stateful
>>   3) stateful snapshot
>>
>> How to efficiently iterate through data that is changing constantly?
>> This problem is harder than it looks.
> 
> Agreed.  I recommend we NOT try to solve that problem.

Unfortunately you do need to pick an interaction model to tie together the first and second pagination requests. At the very least you need to specify consistency guarantees between the two -- which gives them worms juuust enough room to wiggle out of the can.

[Qin]:I think when the client Using page request to get access to the element in the list, he only need to remember the position of last element in the first pagination request and set the number of element he want to request in the pagination requests,
The server doesn't need to keep any additional states, the server only need to support list operation.

A fair answer is 'well, they are not tied together and if the datastore moves, you are SOL' ... but then how do you make forward progress with enough consistency to be useful in the real world? :)

[Qin]: I think it doesn't matter whether the list will grow and add new elements, we could still use last element position and count of elements in the list that need to be queried to retrieve additional elements we want.

At the end of the day, you will end up creating some state on the server, which the server will need to be free to revoke at any time (due to resource constraints, or whatever implementation-specific reasons).

Regards,
Robert

---

From: Robert Varga <[email-masked]>
Date: Wed, 30 Sep 2020 10:39:15 +0200

> Hi, Robert:

Hellow Qin,

> The server doesn't need to keep any additional states, the server only need to support list operation.

That is assuming the list in question has iteration order which is
stable. I do not believe this is something RFC7950 mandates on anything
except ordered-by=user.

> [Qin]: I think it doesn't matter whether the list will grow and add new elements, we could still use last element position and count of elements in the list that need to be queried to retrieve addi…

So let's say the list has 4 elements A, B, C, D.

1) The first request returns items A, B, C.
2) An item is inserted before C, so that the list is E, A, B, C, D.
3) What does the second request return?

Similarly:

1) The first request returns items A, B, C.
2) An item is deleted before C, so that the list is B, C, D.
3) What does the second request return?

Pagination is deceptively hard.

Regards,
Robert

---

From: Kent Watsen <[email-masked]>
Date: Wed, 30 Sep 2020 17:33:41 +0000

Hi Robert,

> stable. I do not believe this is something RFC7950 mandates on anything

If not “ordered-by user”, then its “ordered-by system” that, as RFC 7950 says, "the server is free to sort the list entries in any reasonable order.”  This is a stable ordering, IMO.

> Pagination is deceptively hard.

Is your conjecture that the solution should enable something akin to cursors?  Would this be an advanced feature that a server might support on a list-by-list basis?   Maybe "node-tags” could be useful here too…

K.

---

From: Robert Varga <[email-masked]>
Date: Wed, 30 Sep 2020 22:03:58 +0200

> If not “ordered-by user”, then its “ordered-by system” that, as RFC 7950 says, "the server is free to sort the list entries in any reasonable order.”  This is a stable ordering, IMO.

It's been quite some time since I did lawyer-reading the RFCs, but for
the sake of argument:

- is use of hash maps for keyed lists okay, hence the sort order is the
encounter order based on the contents?
- if so, does that order remain the same even across server restarts?

I am not sure what the litmus test for 'reasonable' would look like, I
am afraid.

> Is your conjecture that the solution should enable something akin to cursors?  Would this be an advanced feature that a server might support on a list-by-list basis?   Maybe "node-tags” could be us…

If the requirement is to really just have an iterator, which breaks when
the list changes, then a node-tag+offset would be sufficient. But then
you could end up in a situation where you will never traverse the list
simply because its rate of change exceeds your ability to traverse it.

The path forks quite a bit if you want something more specific, like:
"visit all elements in any order, i.e. additions do not break iteration".

If we have requirements towards that level of complexity, then yes, I
would very much prefer if there was a cursor-like resource associated
with an ongoing pagination request.

If I squint just a little bit, the first paginated request is not that
different for a (one-shot) subscription to receive notification of all
list entries. Subsequent requests are fetches from that notification
stream... which shows my reactive systems bias :)

Regards,
Robert

---

From: Hongwei Li <[email-masked]>
Date: Wed, 30 Sep 2020 18:54:24 -0400

On Wed, Sep 30, 2020 at 4:04 PM Robert Varga <[email-masked]> wrote:

> > If not “ordered-by user”, then its “ordered-by system” that, as RFC 7950
> says, "the server is free to sort the list entries in any reasonable
> order.”  This is a stable ordering, IMO.
>
> [HL] I would say there is no guarantee on the stable ordering. And the
status may change across server restarts.

> > Is your conjecture that the solution should enable something akin to
> cursors?  Would this be an advanced feature that a server might support on
> a list-by-list basis?   Maybe "node-tags” could be useful here too…
>
> [HL] In the above examples, they are more of dynamic linked lists with
multiple threads making operations on the lists.
The index or position parameter can't be used to get the same values as
they change with system running.
However pagination can be done on snapshot. It means the server can send
data in pages (some or all) once the request is made.
This also complies with the characteristic of a running system.

> Regards,
> Robert
>
> _______________________________________________
> netconf mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netconf
>

---

From: Kent Watsen <[email-masked]>
Date: Wed, 30 Sep 2020 23:56:08 +0000

Hi Robert,

> I am not sure what the litmus test for 'reasonable' would look like, I

Perhaps it’s derived from the next sentence:

	The "description" string for the list may suggest an order
	to the server implementor.

This suggests that the intention is that servers should be able to at least *return* a stable order.   How a server achieves this (given its DB-backend, etc.) is implementation-specific.  

> with an ongoing pagination request.

Ack.

And the tradeoffs aren’t even just "easy/potentially-imperfect" vs. "hard/perfect", as resources come into play, and the scales tip after a number of successive calls.

FWIW, for CT-queries, RESTCONF's Etag/Last-Modified tags can be used to catch a potential imperfect response.

> stream... which shows my reactive systems bias :)

Yes, streaming is goodness, but there’s generally a need for the most-recent to be on-box also.  That said, we could conclude that streaming SHOULD be used to export very-fast logs and therefore easy/potentially-imperfect is “good enough” for queries.

Streaming only applies the CF lists holding time-series data (e.g., logs), which is an important part, but not the only part, being discussed.  Maybe different “requirements”, as you say, apply to CF vs CT lists?

K.