Modify the SendQueue in order to persist the error that cause the event
to fail to send as a `QueueWedgeError`. The `QueueWedgeError` is not a
1:1 mapping for all kinds of errors, but holds variant and information
that the client can react to in order to propose "quick fixes"/solution
before retrying to send.
Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/3973
Also fixes https://github.com/element-hq/element-x-ios/issues/3287
because when a timeline reset occurs the fail to send reason is also
lost.
This PR starts with a refactoring commit
e7696003e8
to introduce the new `QueueWedgedError` and move the logic that was in
the ffi layer to convert api errors to SendState error variant. This
`QueueWedgedError` can be directly use in the `SendingFailed` variant
and expose to ffi.
Second commit
109c133746
adds the persistence, `QueuedEvent` now have an optional error field
instead of a `is_weged` boolean. Same for LocalEchoContent::Event.
Adds also Migration for sqlite and indexeddb
Co-authored-by: Benjamin Bouvier <benjamin@bouvier.cc>
Changelog: We now persist the error that caused an event to fail to send. The error `QueueWedgeError` contains info that client can use to try to resolve the problem when the error is not automatically retry-able. Some breaking changes occurred in the FFI layer for `timeline::EventSendState`, `SendingFailed` now directly contains the wedge reason enum; use it in place of the removed variant of `EventSendState`.
This will only apply to `async_test` functions, but I think this is a
win:
1. for consistency within the codebase, since I've started doing so in
many places,
2. because these function names will clearly identify these functions as
tests, in the call tree interfaces, when rendered using the LSP
show-callers/show-callees functionality.
This was copied from SqliteStateStore, but the reason
that they are separated there is because some migrations
require the store cipher.
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Setting the version number only when all migrations are done
means that the version will be wrong if a migration fails.
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Allows to save media in a different path than the state store.
This adds a "last_access" field to the SQLite implementation, to prepare
for future work on a media retention policy.
This removes the IndexedDB media cache implementation, because as far as
I know it is currently unused, and I have no idea how to implement
efficiently the planned media retention policy with a key-value store.
Closes#1810.
- [x] Public API changes documented in changelogs (optional)
---------
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Most times we pulled an InboundGroupSession from the sqlite DB, we were
overriding whatever value for `backed_up` was stored inside the pickled
value, and using the value stored in the SQL column.
But when we pulled a single InboundGroupSession from the DB by ID, we
did not override it.
I am fairly sure this was an accidental oversight, so this change
corrects it, and unifies the code with other places we create these
objects.
ReadOnlyDevice is not particularly useful as a description of why we
have two device types. This commit renames it into DeviceData, as this
struct is used to hold the device keys and additional local device data.
I'm not quite sure why it took me so long to come up with a better name.
Please forgive me past readers.
The test database was created using a slightly modified `oidc-cli`
example, to turn of the database encryption, on commit
d6dca91df86413b0cbf193a4be191835dd81862e
First off, this patch removes the
`RoomInfoNotableUpdate::trigger_room_list_update` field. It is replaced
by a `reasons: RoomInfoNotableUpdateReasons` 8-bit unsigned integer. It
addresses the following issues:
1. When a subscriber receives a `RoomInfoNotableUpdate`, they have no
idea what has triggered this update.
2. In
`matrix_sdk_base::sliding_sync::BaseClient::process_sliding_sync_e2ee`,
we were triggering an update even if the latest event wasn't
modified: it is a false-positive, it was a bug and a waste of
resources. Now it's more refined, see the why below.
Second, this patch removes the second `trigger_room_list_update`
argument of `matrix_sdk_base::BaseClient::apply_changes`. This method
now knows where to find the reasons for the room info notable updates,
see next point.
Third, this patch adds a new
`matrix_sdk::StateChanges::room_info_notable_updates` field which is a
B-tree map between an `OwnedRoomId` and a
`RoomInfoNotableUpdateReasons`. The idea is that all places that receive
a `StateChanges` can also create a room info notable update with a
specific reason. This is a finer grained mechanism, and it avoids to
pass new arguments everywhere. It's cleaner.
Finally, it's easier than ever to add a new reason and to propagate it
to subscribers.
It's currently possible for integ test results to leak from one test run to the
next (for example, the indexeddb stores hang around in the browser), causing
bad test results.
Extend the test setup routine to clear out the store before the test starts.
Using `SendHandle::abort()` after the event has been sent would look
like a successful abort of the event, while it's not the case; this
fixes this by having the state store backends return whether they've
touched an entry in the database.
It also resets the wedged state, so that the queue will retry to send
this event later. This will show useful in the following case: when an
event is too big, we can now retry to send it, even if it was blocked,
by splitting the event instead of copy/abort/recreate it.
It turns out that so as to be able to read the room ids, they need to be
*values*, not only *keys* (since keys are one-way hashed). This means we
need to duplicate the room_id field in indexeddb/sqlite, so each entry
contains both the room_id as a key (for queries) and as a value (to
return it).
Since there's no meaningful migration we can apply, the way to go is to
drop the pending events table and recreate it from the ground up. It is
assumed that no one has used the store on indexeddb; otherwise the
workaround would be to drop and recreate it.
This PR is the first piece of the breakdown of the following PR: https://github.com/matrix-org/matrix-rust-sdk/pull/3439 where only the core functionalities of the feature are implemented, without addressing the issue of editing and replying to events that have not yet been paginated.
Use a Bloom filter to keep track of which events we have already reported to the parent UTD hook.
We load the data from database on startup, and flush it out immediately on every update.
Using async when not required will increase compile times, and propagate async-ness to the callers, transitively.
See also the [lint description](https://rust-lang.github.io/rust-clippy/master/#/unused_async).
Since we only had a few false positives, I've enabled it by default.
When we add a batch of inbound group sessions to the store, if they came from a
backup, we need to record which backup version they came from.
`CryptoStore::save_changes` doesn't give us an easy way to set the backup
version (we could add it to the `Changes` struct, but ugh).
So, we add a new method `save_inbound_group_sessions` which takes the backup
version as a separate param. This works fine, because whenever we import
sessions there are no other changes to store.
The new method isn't used outside of tests yet -- that comes in a follow-up
commit.