-
-
Notifications
You must be signed in to change notification settings - Fork 829
Conversation
Please include the fix for filtering canonical and alternative aliases from #4260 |
f304b82
to
32ba47b
Compare
b8edbb4
to
d461643
Compare
ec4fbdc
to
3a5e640
Compare
Note to self: this needs to deal with the massive conflict that is #4593 |
This is to identify how bad of a state we're in to start with.
This does a number of things (sorry): * Estimates the type changes needed to the dispatcher (later to be replaced by #4593) * Sets up the stack for a whole new room list store, and later components for usage. * Create a proxy class to ensure the app still functions as expected when the various stores are enabled/disabled * Demonstrates a possible structure for algorithms
This is to get around the problem of a slow dispatch loop. Instead of slowing the whole app down to deal with room lists, we'll just raise events to say we're ready. Based upon the EventEmitter class.
This is the fruits of about 3 attempts to write code that works. None of those attempts are here, but how edition 4 could work is at least documented now.
Maybe we can speed up the algorithm if we know why we're doing the update.
Instead putting the tag handling in the Algorithm class
Sorting and ordering has now been split apart. The ImportanceAlgorithm also finally makes use of the sorting. So far metrics look okay at 3ms for a simple account, though this could potentially get worse due to the multiple loops involved (one for tags, one for categories, one for ordering). We might be able to feed a whole list of rooms into the thing and have it regenerate the lists on demand.
This is largely meant to prove the algorithm works and nothing more.
A possible approach to handling the various triggers for recategorizing rooms.
See comments within for details on what this means.
For now at least. We shouldn't encounter this case until we get around to adding support for newly-joined rooms.
3a5e640
to
b7ba9b3
Compare
This is slated for element-hq/element-web#13635 (already recorded) |
let metaData = null; | ||
|
||
// Is the tag ordered manually? | ||
if (newTag && !newTag.match(/^(m\.lowpriority|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure that JS will cache the regexp properly - i'd play it safe and precompile it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same as what was there before, and for the old room list store - I suspect the whole file will need replacing eventually with the new room list work.
*/ | ||
|
||
interface IProps { | ||
room: Room; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably being terribly thick, but: how does RoomTile2.tsx know when the fields of room
changes, such that it should go re-render itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currently it doesn't, which makes it pretty useless as a component. This is why it's a skeleton :p
* @param {T|*} newState The state to update in the store using Object.assign() | ||
*/ | ||
protected async updateState(newState: T | Object) { | ||
await this.lock.acquireAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused about why we need this –– there's no sign of concurrency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The concurrency comes from the usage, not this class. It's entirely possible that 2 functions call setState()
at the same time, leading to a very confused state. By locking the state first, we hopefully end up with a more linear sequence of events.
The room list store is still somewhat vulnerable to concurrent events and might need locks as time progresses too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you don't mean literally "at the same time", since there's no multi-threading happening... So this is about path A calling updateState
and then path B calling updateState
before the result of A's change has propagated and folded into path B?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, sorry. Not exactly at the same time but two concurrent calls being called over top of each other (because multithreading is just pausing code in different branches).
The nature of the async store kinda makes it required as we'd otherwise run into issues eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks great! 😁
The main open question for me is around the locking, which so far I don't quite understand... but I assume there must be some reason or else you wouldn't have added it, so I assume we can go back and forth on that without blocking the whole review on it.
@@ -0,0 +1,247 @@ | |||
/* | |||
Copyright 2015, 2016 OpenMarket Ltd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much is copied vs. new? Maybe remove the old copyright lines if basically all new...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's about 80/20 copied.
@@ -0,0 +1,227 @@ | |||
/* | |||
Copyright 2015, 2016 OpenMarket Ltd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly unsure if these dates make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also about 80% copied.
@@ -0,0 +1,220 @@ | |||
/* | |||
Copyright 2015, 2016 OpenMarket Ltd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as with other files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this one is only 60-70% copied
@@ -0,0 +1,125 @@ | |||
# Room list sorting | |||
|
|||
It's so complicated it needs its own README. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing all of this down! 🤩
const receiptUsers = Object.keys(payload.event.getContent()[eventId]['m.read'] || {}); | ||
if (receiptUsers.includes(myUserId)) { | ||
// TODO: Update room now that it's been read | ||
console.log(payload); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the be removed for landing here and in the rest of the branches...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll get removed when the associated TODO is dealt with. It doesn't spam anything unless you opt in to this horrible excuse of a room list.
src/stores/room-list/algorithms/tag_sorting/AlphabeticAlgorithm.ts
Outdated
Show resolved
Hide resolved
Thanks @jryans for taking a look 😄 The async locking stuff can definitely be discussed out of band (or here, or on another PR, or somewhere) - we have a little while before this is even remotely close to primetime. |
Fixes element-hq/element-web#11743 (this PR has the core algorithm described in the issue)
Includes & requires #4593 (dispatcher types)(merged)Requires element-hq/element-web#13675
Requires element-hq/element-desktop#87
Making this behave correctly is left for element-hq/element-web#13635
To manage expectations: This is not as great as it sounds. The room list is in fact rewritten, but there are a whole bunch of missing features that people will have grown to expect. For example, the current room isn't highlighted, filtering doesn't work, and the LLP does nothing against this room list. This is intentional - the diff for the algorithm is large enough as is, so there's no real benefit to having someone review a million lines of feature implementation alongside computing science theory.
Many of the components have half-baked implementations, such as badges: badges show up on initial render but there's TODO comments to update them dynamically. This is due to an arbitrary line drawn in the sand for this PR: the idea was to ensure that the component structure would work to write features, but not necessarily burden the reviewer with trying to figure out how a feature works.
When reviewing, please put more attention on the algorithm and less so the components. The components are intentionally skeletons.
This also doesn't have tests. It's a proof of concept with the absolute bare minimum UI to be considered potentially useful in performance metrics. Tests will come in a later PR when the implementation stabilizes. For now you'll have to trust me that it works :D
The documentation for how this works is in the code. Normally it would be here in this description, likely in place of these exact words, however due to the complexity involved it seemed best to dump the docs directly in the code, making the code worse.
With that being said, here's some implementation notes: This new PR bypasses trying to make the existing room list store and related stack go faster, and instead builds a whole new stack from the ground up. This is taking the form of almost-MVVM with async stores (invented in this PR) where the components get told to render an object of things and to figure out the rest. The most notable difference of this is in the room tiles: previously the component was required to be told what the badge counts and such were, and the new room tile just figures it out. It's not a perfect implementation though - there's some cleanup work still to be done.
For future adventurers: the algorithms are fundamentally different from each other at a technical level with very little reusable code, so they've been split into two kinds: Sorting and List algorithms. The sort algorithms largely define the ordering for a sublist/tag, and the list algorithm defines what to do with the rooms as a higher order sort.
At one point this had all the tagging logic in the RoomListStore2 class, but that was incredibly slow (>500ms) so that was scrapped and the algorithm classes were starting to take shape. This in theory should give a bit of a boost and not cause headaches when trying to read thousands of lines of code.
Targets to beat or match:
This PR's metrics haven't been measured because the account I would normally use is on a homeserver that can barely handle sending a read receipt right now. It's expected to be at least on par with the numbers above based on limited small-case testing.