Add feed generator cursor specification at protocol level #2144
Replies: 2 comments
-
(carrying over my thoughts from Discord) FWIW, in general cursors are meant for short-term iteration over a list of results, so it might be worth to introduce a separate long-term token (as well as a feed flag to indicate the support for it). Given that the feed generators are opaque, and there's no contract for them even returning a stable set of posts, it doesn't make sense to require all of them to support this. So a client must be able to determine if a given feed supports this or not. |
Beta Was this translation helpful? Give feedback.
-
(migrated this from an issue on the |
Beta Was this translation helpful? Give feedback.
-
Apologies if opening an issue here is inapropriate. I was told to do so on the API touchers Discord, and it might make sense to consider this as atproto is still in its early stages.
I and quite a few others are trying our hands on writing alternative clients for BlueSky. One of the biggest problems we face is the under-specified nature of feed generator cursors.
We all would like to implement two features:
However, given the current nature of feed generator cursors (and their result sets of items), this is currently not possible. I'm splitting this into two problems.
Problem 1: Resume viewing the feed from where you left
Let me illustrate the issues we have with cursors and resuming viewing of feeds where one has left off. The following assumes we are talking to the app.bsky.feed.getFeed endpoint. Similar things hold true for other cursor-based endpoints.
getFeed()
.getFeed()
FeedViewPost
s on device.Now, this works in theory. In practice, the cursor used in step 10 may have become invalid, point to somewhere wrong in the stream, or a myriad of other things that could go wrong. Feeds are not necessarily chronological, which often renders cursors unstable/not resumable.
A client app developer can not know if the cursor that was saved is still valid. Feed generators generally do not document whether their cursors are stable/resumable or not.
I believe a flag on the
GeneratorView
indicating whether cursors are stable/resumable would go a long way to help us.If a generator can not provide stable/resumable cursors, client apps can tell the user to not expect resumable viewing of that feed, and avoid rendering possible errornous results, e.g. duplicate or incorrectly ordered feed items.
Problem 2: Fetch the next X newer items
Cursors get us into the past. There is no equivalent for going into the "future" so to speak. Let me illustrate with another user/client app flow:
getFeed()
without a cursor, and with a limit of1
, checking if the returned feed item is part of the already known items or not. If it is not, we know there are new items. We do not know how many at this point.The reason for this "failure" is that we can not construct cursors for fetching newer items than the one's we've seen before, due to the opaque nature of the cursors, or simply because the feed generator can practically not support it, e.g. because they are not chronological.
One strategy we try to employ at the moment to fetch newer items goes like this:
getFeed()
without a cursorThis only works for chronological/ordered feeds, where we won't see the same item twice. Otherwise the overlap test will probably fail in some scenarios.
An alternative approach exploits the fact that many feeds use a
<utc-timestamp>::<cid_of_last_seen_post>
cursor format and allow constructing cursors into "the future". That way lies misery though: we can't be sure if a feed generator will actually honor the format properly, like theFollowing
generator does (which isn't a generator like the others, but has its own endpointgetTimeline()
).I believe a flag on the
GeneratorView
indicating whether a feed is chronological/ordered and a cursor specification that allows client apps to construct cursors for queries like "give me 25 items that are newer than this item" would be a great addition on the protocol levelAgain, sorry if this doesn't belong here. Figured I'd try my luck.
Beta Was this translation helpful? Give feedback.
All reactions