Commit Graph

5244 Commits

Author SHA1 Message Date
Ivan Enderlin
ca5cabb7e1 doc(sdk): Fix a typo. 2023-03-15 18:08:19 +01:00
Ivan Enderlin
7a2b1e6e1f doc(sdk): Fix a typo. 2023-03-15 17:59:11 +01:00
Ivan Enderlin
c0f84bb8da test(sdk): Fix tests and improve speed.
To improve the speed, we simply reduce the numbers of rooms involved in
the test.
2023-03-15 17:54:39 +01:00
Ivan Enderlin
a2dcfa905f fix(sdk): Fix, test, and clean up SlidingSyncList.
This patch should ideally be split into multiple smaller ones, but life
is life.

This main purpose of this patch is to fix and to test
`SlidingSyncListRequestGenerator`. This quest has led me to rename
mutiple fields in `SlidingSyncList` and `SlidingSyncListBuilder`, like:

* `rooms_count` becomes `maximum_number_of_rooms`, it's not something
  the _client_ counts, but it's a maximum number given by the server,

* `batch_size` becomes `full_sync_batch_size`, so that now, it
  emphasizes that it's about full-sync only,

* `limit` becomes `full_sync_maximum_number_of_rooms_to_fetch`, so that
  now, it also emphasizes that it's about ful-sync only _and_ what the
  limit is about!

This quest has continued with the renaming of the `SlidingSyncMode`
variants. After a discussion with the ElementX team, we've agreed on the
following renamings:

* `Cold` becomes `NotLoaded`,
* `Preload` becomes `Preloaded`,
* `CatchingUp` becomes `PartiallyLoaded`,
* `Live` becomes `FullyLoaded`.

Finally, _le plat de résistance_.

In `SlidingSyncListRequestGenerator`, the `make_request_for_ranges`
has been renamed to `build_request` and no longer takes a `&mut self`
but a simpler `&self`! It didn't make sense to me that something
that make/build a request was modifying `Self`. Because the type of
`SlidingSyncListRequestGenerator::ranges` has changed, all ranges now
have a consistent type (within this module at least). Consequently, this
method no longer need to do a type conversion.

Still on the same type, the `update_state` method is much more
documented, and errors on range bounds (offset by 1) are now all fixed.

The creation of new ranges happens in a new dedicated pure function,
`create_range`. It returns an `Option` because it's possible to not be
able to compute a range (previously, invalid ranges were considered
valid). It's used in the `Iterator` implementation. This `Iterator`
implementation contains a liiiittle bit more code, but at least now
we understand what it does, and it's clear what `range_start` and
`desired_size` we calculate. By the way, the `prefetch_request` method
has been removed: it's not a prefetch, it's a regular request; it was
calculating the range. But now there is `create_range`, and since it's
pure, we can unit test it!

_Pour le dessert_, this patch adds multiple tests. It is now
possible because of the previous refactoring. First off, we test the
`create_range` in many configurations. It's pretty clear to understand,
and since it's core to `SlidingSyncListRequestGenerator`, I'm pretty
happy with how it ends. Second, we test paging-, growing- and selective-
mode with a new macro: `assert_request_and_response`, which allows to
“send” requests, and to “receive” responses. The design of `SlidingSync`
allows to mimic requests and responses, that's great. We don't really
care about the responses here, but we care about the requests' `ranges`,
and the `SlidingSyncList.state` after a response is received. It also
helps to see how ranges behaves when the state is `PartiallyLoaded`
or `FullyLoaded`.
2023-03-15 16:57:29 +01:00
Ivan Enderlin
c6c259144a chore(sdk): Rename enum variants to be consistent across all the modules. 2023-03-13 14:29:12 +01:00
Ivan Enderlin
032356566e chore(sdk): Rewrite a small part of the code to make it clearer. 2023-03-13 14:07:36 +01:00
Ivan Enderlin
35bb18a1e8 feat(sdk): Add more Sliding Sync logs.
This patch adds more logs around `SlidingSync` to ease debugging sessions.
2023-03-13 11:41:20 +01:00
Ivan Enderlin
3c25ad1489 doc(sdk): Remove a FIXME that is actually fixed.
The #1386 issue is closed. Yepee.
2023-03-13 09:05:32 +01:00
Jonas Platte
8d83a996a6 Handle another new clippy lint
Issue about false positives:
https://github.com/rust-lang/rust-clippy/issues/10482
2023-03-11 13:13:50 +01:00
Jonas Platte
595e34aad5 Silence new clippy lint for generated code 2023-03-11 13:13:50 +01:00
Jonas Platte
cc35ee72b8 Upgrade eyeball to 0.4.0 2023-03-11 13:13:50 +01:00
Jonas Platte
b148ea2fb1 Bump locked version of clap
To work around this clippy bug:
https://github.com/rust-lang/rust-clippy/issues/10421
2023-03-11 13:13:50 +01:00
Mauro
2bb66f0f2e bindings: Expose leave and reject_invitation functions to FFI 2023-03-10 18:07:13 +01:00
Ivan Enderlin
331ea35be6 fix(sdk): SlidingSync has a lock for both pos _and_ delta_token
fix(sdk): `SlidingSync` has a lock for both `pos` _and_ `delta_token`
2023-03-09 17:10:42 +01:00
Ivan Enderlin
b9fd451d54 feat(sdk): Move Client.root_span inside ClientInner
feat(sdk): Move `Client.root_span` inside `ClientInner`
2023-03-09 17:03:27 +01:00
Ivan Enderlin
3511a4a053 fix(sdk): SlidingSync has a lock for both pos _and_ delta_token.
This patch updates `SlidingSync.pos` and `.delta_token`. Each field has their
own lock. It's annoying because they must updated at the same time to not be
out-of-sync.

So a new field `SlidingSync.position` of type `SlidingSyncPositionMarkers` is
created. It holds `pos` and `delta_token. This new field is behind a single
`RwLock`.
2023-03-09 16:47:11 +01:00
Ivan Enderlin
7f52292e92 chore(sdk): Remove useless comment. 2023-03-09 16:43:41 +01:00
Ivan Enderlin
cc69efc3f8 feat(sdk): Move Client.root_span inside ClientInner. 2023-03-09 15:12:11 +01:00
Richard van der Hoff
508f1bc976 Fix races between /sync and /keys/queries (#1619)
The comments in the code should explain the general approach, but to give an overview:

We assign a unique sequence number to each device-list-invalidation notice, and keep track 
of the sequence number at which each user was most recently invalidated. Then, when we 
build a `/keys/query` request, we take note of the current sequence number. Finally, when 
we get the response from that `/keys/query` request, we compare that sequence number
with the most-recent-invalidation of each user that is now supposedly up-to-date. All 
of that means that we can see if the user has been invalidated *since* we built the 
`/keys/query` request, in which case our request may have raced against the new device,
so we do not mark the user as up-to-date.

To make that work, we need to keep track of the sequence number for in-flight `/keys/query`
requests; we do that in the `IdentityManager`. Since there should only ever be at most one
batch of requests in flight, that is relatively easy; however, we also record the request ids
just to check that the application isn't doing something weird.

There is no need to persist the sequence numbers to permanent storage: provided the
`IdentityManager` and `Store` objects have a lifetime at least as long as an in-flight
`/keys/query` request, it is sufficient just to retain the `dirty` bit in permanent storage,
and then, when we reload the ephemeral `Store` cache, to treat everything with a `dirty`
bit as a "new" invalidation.

Fixes: #1386.
2023-03-09 10:57:20 +00:00
Ivan Enderlin
da5c79482b feat(ffi): Rethink TaskHandle
feat(ffi): Rethink `TaskHandle`
2023-03-08 17:21:52 +01:00
Ivan Enderlin
4996a19b31 feat(ffi): Rethink TaskHandle.
With https://github.com/matrix-org/matrix-rust-sdk/pull/1601,
`TaskHandle::with_callback` is no longer necessary.

This patch updates `TaskHandle` as follows:

1. Before, the `handle` and `callback` fields were not mutually exclusive!
   Indeed, the `callback` field was used as an abort mechanism, but _also_ as a
   finalizer, i.e. a code that runs _after_ the cancellation of `handle`. Now
   that the callback-based solution is no longer used, we can keep one usage for
   this field and rename it `finalizer`.
2. The `handle` field is no longer optional, as it will always be set.
3. The `with_callback` method is renamed `new` as it's now the only constructor.
4. The `set_callback` method is renamed `set_finalizer`.

Tadaaa.
2023-03-08 17:09:47 +01:00
Ivan Enderlin
d720861fbd fix(bindings): SlidingSync.sync returns an immediately cancellable TaskHandle
fix(bindings): `SlidingSync.sync` returns an immediately cancellable `TaskHandle`
2023-03-08 16:39:09 +01:00
Ivan Enderlin
c517f38ec8 sliding-sync: process receipt extension response
sliding-sync: process receipt extension response
2023-03-08 16:29:56 +01:00
Ivan Enderlin
ac863409bb doc(sdk): Remove notion of fairness. 2023-03-08 16:20:50 +01:00
Kegan Dougal
417008cc87 Clippy 2023-03-08 15:14:59 +00:00
Ivan Enderlin
5dd404d2f1 doc(sdk): Precise in which order SS responses will be handled. 2023-03-08 16:09:05 +01:00
Kegan Dougal
2c0466a8cc Unbreak tests; don't shadow 2023-03-08 15:03:41 +00:00
kegsay
aec65c818b Update testing/sliding-sync-integration-test/src/lib.rs
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-03-08 14:51:26 +00:00
Jonas Platte
0d9d130833 Replace StateStoreDataKey::encoding_key by associated constants 2023-03-08 15:51:13 +01:00
Jonas Platte
26e259455a Adhere to module naming conventions 2023-03-08 15:51:13 +01:00
Ivan Enderlin
2f637cda6f doc(sdk): Add note about fairness of the SS lock. 2023-03-08 15:33:40 +01:00
Ivan Enderlin
64ae77ec70 feat(sdk): Run SS response handling in a single non-cancellable block. 2023-03-08 15:15:16 +01:00
Jonas Platte
932cf2ad99 Fix experimental features not compiling without encryption 2023-03-08 15:03:20 +01:00
Jonas Platte
68f8ed5a92 Add futures-util as a workspace dependency
… and always activate its `alloc` feature.
Fixes building matrix-sdk without the e2e-encryption feature.
2023-03-08 15:03:20 +01:00
Kegan Dougal
4670142a83 Clippy 2023-03-08 13:21:56 +00:00
Kegan Dougal
9a53602d73 Formatting 2023-03-08 12:58:48 +00:00
Kegan Dougal
48bf20fcca Add integration test for receipts in sliding sync 2023-03-08 12:53:23 +00:00
Mauro
be6c7c8b4c Add user avatar URL caching 2023-03-08 13:30:46 +01:00
Ivan Enderlin
832146b43d feat(sdk): Create SlidingSyncInner.
Move all `SlidingSync`'s fields into a new `SlidingSyncInner` type, and then
update `SlidingSync` to contain a single `inner: Arc<SlidingSyncInner>` field.

First off, it's much simpler to understand what's behind an `Arc` for
“clonability” of `SlidingSync`, and what's not. We don't need to worry about
adding a new field that is not behind an `Arc` for a specific reason or
anything. The pattern is clear now.

Second, this is required for next commits.
2023-03-08 12:12:58 +01:00
Ivan Enderlin
66d4ced90f chore: Add some inline documentation. 2023-03-08 12:01:57 +01:00
Jonas Platte
5c2915bb6a crypto-ffi: Use uniffi derives for types no longer referenced in UDL 2023-03-08 11:12:11 +01:00
Jonas Platte
fb23cbff97 crypto-ffi: Use UniFFI proc-macros for more OlmMachine methods 2023-03-08 11:12:11 +01:00
Jonas Platte
9fe880d05d Clean up formatting of olm.udl 2023-03-08 11:12:11 +01:00
Jonas Platte
7af2bea2fc Upgrade UniFFI 2023-03-08 11:12:11 +01:00
Kegan Dougal
f1829faa99 Merge branch 'main' into kegan/receipts-ss 2023-03-08 09:33:48 +00:00
Ivan Enderlin
7369010964 feat(sdk): Make SlidingSync::handle_response _sync_, no more _async_.
The idea is to group all async and await points in `sync_once`. It's easier to
think about it.
2023-03-08 09:41:32 +01:00
Ivan Enderlin
07f6a3b345 chore: Remove warnings. 2023-03-08 09:35:47 +01:00
Ivan Enderlin
8f6f20bbe7 fix(bindings): SlidingSync.sync returns an immediately cancellable TaskHandle.
Before this patch, `SlidingSync::sync` was returning a callback-based
`TaskHandle`. It was waiting on the “stream loop” to finish (since it's a long-
poll, it means waiting 2*30s, cf. our code), before checking an atomic flag has
some value to decide whether it was time to leave the loop or not. So when the
user is cancelling this `TaskHandle`, a response (if any) was always handled.
But in the meantime, it was possible to start a new `sync`, and it seems like
it creates bugs.

After this patch, `SlidingSync::sync` now returns a handle-based `TaskHandle`.
It means that cancelling it will cancel the “stream loop” immediately. If
no response was in-flight from the server, that's perfect, no problem. If a
response was in-flight, the inner `pos` of the `SlidingSync` instance won't be
updated as the response won't be handled. So the server will re-send the same
response with the next sync request.

I guess it's better this way. Thoughts?
2023-03-08 09:35:47 +01:00
Ivan Enderlin
6a9cf1f9ce feat(sdk): SlidingSync::stream can match expected responses
feat(sdk): `SlidingSync::stream` can match expected responses
2023-03-08 09:14:32 +01:00
Ivan Enderlin
f8ce49cc49 chore: Add documentation. 2023-03-08 08:56:38 +01:00