This patch extracts fields from `RoomEventCacheState` and move them
into `RoomEventCacheStateLock`. This lock provides 2 methods: `read`
and `write`, respectively to acquire a read-only lock, and a write-only
lock, represented by the `RoomEventCacheStateLockReadGuard` and the
`RoomEventCacheStateLockWriteGuard` types.
All “public” methods on `RoomEventCacheState` now are facade to the read
and write guards.
This refactoring makes the code to compile with the last change in
`EventCacheStore::lock`, which now returns a `EventCacheStoreLockState`.
The next step is to re-load `RoomEventCacheStateLock` when the lock is
dirty! But before doing that, we need this new mechanism to centralise
the management of the store lock.
This patch changes `EventCacheStoreLockState` to own a clone of
the inner store. It helps to remove the `'a` lifetime, and so it
“disconnects” from the lifetime of the store.
This patch replicates the `is_dirty` and `clear_dirty` methods from
`CrossProcessLock` to `CrossProcessLockGuard`. It allows to get an
access to this API from a guard when one doesn't have the cross-process
lock at hand.
This patch updates `EventCacheStoreLock::lock()` to return an
`EventCacheStoreLockState` instead of an `EventCacheStoreLockGuard`, so
that the caller has to handle dirty locks.
This patch adds the `CrossProcessLockState::map` method along with its
companion `MappedCrossProcessLockState` type. The idea is to facilitate
the creation of custom `CrossProcessLockState`-like type in various
usage of the cross-process lock.
These will use `bridge_trace_id` to map an exising client transaction/span to this one so they'll be displayed as a single one in Sentry.
This is done through the `sentry.trace` field, which will be used by `sentry-tracing` to differentiate these kinds of special spans.
The special fields need to be added on the Span creation, that's why we do it in the constructor instead of just using `span.record(...)` later.
This patch adds a `profile: TimelineDetails<Profile>` field to
`LatestEventValue::Local` in `matrix_sdk_ui::timeline` (and the
corresponding `matrix_sdk_ffi` type).
This patch fixes a race condition where events won't get decrypted
because a room key arrives after the initial decryption attempt but
before the UTD has been persisted in the event cache.
The fix is relatively straightforward, we'd need a synchronization point
for the two different tasks, the event cache which adds events and the
redecryptor which listens to room keys to decrypt events.
A lock could have been used, so the storing and redecrypting of events
becomes synchronized via the storage layer. This approach could have
degraded performance since the event cache needs to handle a lot of
events.
The approach that was chosen here is to let the redecryptor listen to
updates coming from the event cache itself. If the event cache tells us
that it persisted a UTD, we will attempt to decrypt. Upon a successful
decryption we will replace the event in the cache as well.
This patch adds a convenience function for the Update enum. If one only
cares about the items contained in the Update, then they can chose to
use this method to extract them out of the enum.
This patch adds a test confirming that the redecryptor has a race
condition.
Namely, events and room keys are received over two different sync
streams from the homeserver. When events are received over the sync, we
first try to decrypt them, this might fail because the room key hasn't
yet arrived over the other sync stream. The event cache will then
persist the event as a UTD.
At the same time, the redecryptor will listen to room keys that arrive
on the other sync stream. Once the redecryptor gets notified about a
room key, it will attempt to fetch the event from the event cache to
decrypt the event and replace it.
Crucially if the key arrives before the event gets persisted but after
the initial decryption attempt we might never attempt to redecrypt such
an event.
We had an instance where a user joined a room on Element X but did not download
the key bundle, so let's add some logging to help figure out what was going on.