You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The SDK is ripe for supporting threads, which allows parallel topical discussions and reduce confusion. And, it will make it possible to add support for it in embeddings, notably in ElementX, closing the gap with the Element app's feature set.
We'll update this issue as soon as we'll identify the next steps.
Here is the high-level overview of what we're planning to implement:
Make it possible to save threads events in the event cache (even if they haven't been received from sync). We also want to persist and restore a thread's summary to/from persisted storage.
Extract the bundled aggregation from a thread root, and feed it into the RoomEventCache, which forwards it to the ThreadEventCache ONLY if the thread was not known beforehand
Save the bundled thread's latest event into the event cache (don't insert into the thread linked chunk, only save it into the events table with save_event())
Have a linked chunk per thread.
RoomEventCache gets a mapping of thread root id to ThreadEventCache { events: LinkedChunk<...>, } (consider using a specialized gap of ThreadGap { prev_token: Option<String>, next_token: Option<String> }).
Sync appends new events into the thread linked chunk in real-time.
Room back-pagination does NOT propagate events into the thread linked chunk. Otherwise, as soon as we have a gap in the thread, we don't know where the room-backpaginated events should go in the thread.
clear all the ThreadEventCaches upon gappy sync. Indeed we don't know if we missed events in that specific threads, so we don't really have a better choice at the moment (until we get an SSS extension with the list of threads that had updates)
Allow subscribing to a thread by receiving the initial events in that thread, if known, and a stream of VectorDiff<Event> (this will power the thread-focused timeline).
implement back-pagination at the ThreadEventCache level; this will be used by the thread-focused timeline paginate_backwards() method.
Thread persistent storage
Generalize the SQLite backend to hold thread linked chunk. It might be sufficient that a linked chunk's key isn't a room anymore, but a generalized enum LinkedChunkKey { Room(OwnedRoomId), Thread(OwnedRoomid, OwnedEventId) }. Migration = clear all the chunks?
Add a table in storage to store thread summaries separately from the root event; or instead of storing TimelineEvent into storage, store an augmented data structure that also includes a ThreadSummary (⚠ this second alternative would require a migration).
Add a method in the event cache store to upsert_thread_summary
Keep participated in clear, so that we can query for all the threads we've participated to.
For each event that had more than one edit (>1 or >=1 TBD), introduce an edit linked list, to order them relative to each other, and figure out which is the actual latest.
What to do after a gappy sync?
Thread summary
Drop them all upon gappy sync (+ notify)
Refresh all with /context (with 0 events before/after)
❓ What about events which were not thread roots, but may be now?
Thread linked chunk
In a non-persisted world, we can clear the linked chunk of a gappy thread immediately.
Upon gappy sync, do a /threads query to retrieve all the threads and their latest event; if it matches what we knew from the thread linked chunk, mark it as NOT maybe_outdated. If not, start back-pagination until all the thread events are known.
This has been deemed impractical, because /threads can be super slow for large rooms like MatrixHQ. Instead, we could, for each known thread, run a single /relations query from the back, and keep on back-paginating until we know all the events; or let the embedder manually request to back-paginate, like we do for live main timelines.
Likely recompute the thread summary afterwards 👀 (Think about conflicts with sync.)
Read receipts
We want to support thread read receipts. This will not interact with unread status on rooms, yet.
…loader (#5032)
… that allows building a timeline instance specific to a particular
thread root.
Creating a timeline in this mode will start by backpaginating root event
relations with `num_events` and automatically insert the thread root
event when reaching the end. It will include
`RelationsOfType(RelationType::Thread)` but also recurse over the
retrieved events to fetch reactions.
It will not however react to new events received over sync or that the
user sends (for now).
This patch will also help incrementally deliver the upstream client
support for creating such a timeline.
Part of #4833 (meta #4869).
Uh oh!
There was an error while loading. Please reload this page.
The SDK is ripe for supporting threads, which allows parallel topical discussions and reduce confusion. And, it will make it possible to add support for it in embeddings, notably in ElementX, closing the gap with the Element app's feature set.
We'll update this issue as soon as we'll identify the next steps.
Here is the high-level overview of what we're planning to implement:
Interacting with threads
/threads
/relations
Thread-focused timeline
A new timeline focus will be introduced that will represent a thread. Threads will include message-like events, and will be updated in real-time.
TimelineItemContent
layer that holds aggregations #4839RedactedMessage
andUnableToDecrypt
toMsgLike
#4860Thread
timeline focus mode and associated events loader #5032EventFilter
might be sufficient, but if it's not we'll need a different type.TimelineEventKind
withTimelineAction
#4655 so we can only observe aggregations from sync, and apply them in the thread if needs be.Thread data model
Make it possible to save threads events in the event cache (even if they haven't been received from sync). We also want to persist and restore a thread's summary to/from persisted storage.
Some developments are happening here.
Core types
ThreadSummary
:load_or_fetch_event()
method to retrieve it from the cache when needed)ThreadEventCache
, which contains a linked chunk + the thread summary.RoomThreadCache
, which contains a mapping of all the threads roots to theirThreadEventCache
.RoomEventCache
contains exactly oneRoomThreadCache
. Separating them helps separating concerns + testing threads in isolation.Tasks
RoomEvents
event chunks withAllEventsCache
events #3886RoomEventCache
, which forwards it to theThreadEventCache
ONLY if the thread was not known beforehandsave_event()
)RoomEventCache
gets a mapping ofthread root id
toThreadEventCache { events: LinkedChunk<...>, }
(consider using a specialized gap ofThreadGap { prev_token: Option<String>, next_token: Option<String> }
).ThreadEventCache
s upon gappy sync. Indeed we don't know if we missed events in that specific threads, so we don't really have a better choice at the moment (until we get an SSS extension with the list of threads that had updates)VectorDiff<Event>
(this will power the thread-focused timeline).ThreadEventCache
level; this will be used by the thread-focused timelinepaginate_backwards()
method.Thread persistent storage
enum LinkedChunkKey { Room(OwnedRoomId), Thread(OwnedRoomid, OwnedEventId) }
. Migration = clear all the chunks?TimelineEvent
into storage, store an augmented data structure that also includes aThreadSummary
(⚠ this second alternative would require a migration).upsert_thread_summary
participated
in clear, so that we can query for all the threads we've participated to./context
(with 0 events before/after)Upon gappy sync, do a/threads
query to retrieve all the threads and their latest event; if it matches what we knew from the thread linked chunk, mark it as NOTmaybe_outdated
. If not, start back-pagination until all the thread events are known./threads
can be super slow for large rooms like MatrixHQ. Instead, we could, for each known thread, run a single/relations
query from the back, and keep on back-paginating until we know all the events; or let the embedder manually request to back-paginate, like we do for live main timelines.Read receipts
We want to support thread read receipts. This will not interact with unread status on rooms, yet.
The text was updated successfully, but these errors were encountered: