Reduce our reliance on an up-to-date joined rooms cache #16
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Opening this mostly to start a discussion and see how best to proceed with this.
The current joined rooms API is not very safe by default. It caches joined rooms to allegedly to speed up
ensureRoomJoined()
(comment), but also utilizes it in other ways, like ignoring some room events in crypto handling if it doesn't think the user is in a certain room – making the invalid cache a potential source of bugs.Different API calls like
Intent.getJoinedRooms()
(here) warn that joining rooms out of band may cause the Intent API to return incorrect results. To help with that, it exposes a public API to refresh its own cache (Intent.refreshJoinedRooms()
here). The necessity to call this at the right times comes with its own problems, like Appservice membership event handling possibly failing due to triggering Matrix API calls when it doesn't need to. There's a few places where we refresh the entire joined room list rather than applying the membership changes that we know have just happened, which I fixed in this PR.I don't think the worry about externally induced joins not being noticed by the bot-sdk are entirely warranted (we're bound to get the room joined AS event first after all, I don't think there's any way we can miss it even if we didn't trigger it), but this whole mechanism seems like an optimization both premature (joining an already joined room excessively is not an error, and I imagine is pretty cheap) and happening at the wrong layer. The user of the SDK can make a more informed decision if, in their scope, it makes sense to cache such things, or if it's safe to use at all.
This PR slightly reduces our reliance of the joined rooms cache – never making decisions like "should we drop this event" based on its contents, and making public APIs like
getJoinedRooms()
return freshest possible information anyway.refreshJoinedRooms()
should probably be deprecated here, but I do wonder if a proper solution would be just dropping this whole caching from Intent and leaving it up to the SDK user to decide whether they need something like that or not. It is, after all, trivial to implement yourself – I've done just that in my projects, not knowing thatensureRoomJoined()
does the caching by itself.