Commit Graph

104 Commits

Author SHA1 Message Date
Benjamin Bouvier 7c68096237 multiverse: allow setting a proxy
This is handy when running mitmproxy on multiverse.
2024-04-11 16:45:05 +02:00
Kévin Commaille da2abccc0d chore: Disable clippy::assigning_clones lint
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2024-04-02 15:05:41 +02:00
Benjamin Bouvier 4ad79d6d44 multiverse: hide the password by using rpassword to prompt it 2024-03-08 17:44:55 +01:00
Benjamin Bouvier e57a02fd91 multiverse: add support for backpagination 2024-03-08 17:37:26 +01:00
Benjamin Bouvier c41f7975b3 labs: turn rrrepl into a timeline client 2024-03-08 16:08:29 +01:00
Benjamin Bouvier 5386e9e838
event cache: have a single `EventCache` instance per `Client`, at most (#3136)
* event cache: move it to the main SDK crate

* event cache: add requested Debug impl to `RoomEventCacheUpdate`

Somehow the compiler asked for it now...

* event cache: add missing copyright notice to store file

* event cache: use a weak reference to the client internally

This will make it possible to have the `Client` own an `EventCache` without a reference
cycle.

* event cache: move the spawned task to its own function

* event cache: move RwLock from EventCache::inner to the only mutable field inside EventCacheInner

* event cache: have the Client own *the* event cache

The goal is to have a unique EventCache instance overall, that's available from everywhere in
the SDK, notably when creating timelines for rooms.

Because the event cache only owns a weak reference to the client, it means the Client still
can be dropped, In turn, this will close its sender of `RoomUpdates`, which will gracefully
close the task spawned in `EventCache::new` after it's done handling the latest updates.

* event cache: process room updates one at a time

* timeline: use the client-wide event cache instead of spawning one per timeline

This now means that we're passing the "initial events" to the event cache just before initializing
the timeline. As a result, there might be previous events that the event cache saw (coming from
sync), but now we can't decide where to put them; drop previously known events in that case.

* event cache: hey, turns out we don't even need the weak back-link

Keeping it as a separate commit, to make it easier to revert later.

* event cache: remove unused errors

Keeping the error type and results, though, because we might have store errors soonish.

* fixup! event cache: move the spawned task to its own function

* event cache: manually subscribe to the event cache

It was a bad idea to have it enabled by default, since some users may not be interested in all
updates for all rooms (e.g. bots). Instead, we make it so that the event cache must be
explicitly subscribed to, and we do it in two cases:

- in the UI `TimelineBuilder::build` method, because we're interested in updates to the current
  room,
- in the `RoomListService`, because we *will* be interested in updates to room derived data (e.g.
  unread counts, read receipts, and so on).

This avoids a bit of fiddling when creating the event cache in the client.

This is resilient when a parent Client is forked into a child Client, because the child
`EventCache` share the same subscription as the parent's.
2024-02-19 12:39:31 +00:00
Benjamin Bouvier 1e24fbc72d rrrepl: use `Timeline::mark_as_read` there too 2024-02-15 18:09:57 +01:00
Benjamin Bouvier 06fe8a8f32 event graph: add an initial implementation of the event graph
This is mostly a demonstration of how to plug this with the timeline, and how little it changes as a result.

Remove read receipts
2024-01-30 23:27:22 +01:00
Jorge Martin Espinosa c418f0e6ba
timeline: Add `TimelineEventTypeFilter` (#3025)
Adds a `TimelineEventTypeFilter` enum that either returns only events whose event_type is included in a set of allowed event types, or all events but those whose event types are in a list of excluded event types.

Also adds `TimelineEventTypeFilter` so the clients can use it to define those lists of event types, which are then converted to ruma `TimelineEventType` and used for filtering.

---

* matrix-sdk-ui: add `TimelineEventTypeFilter` to filter timeline events by either including only those of some event types or all but the ones that match those event types.

* ffi: add bindings to `TimelineEventTypeFilter` and `FilterTimelineEventType` so we can provide these event types from the FFI clients

* Fix format

* Fix tests

* Fix format again (using nightly toolchain)

* Remove `all_filter_...` functions as there is no right way to support it at the moment and they're just helpers

* Improve tests

* Make `TimelineEventFilterFn` public so it can be used in several layers.

* Make `TimelineEventTypeFilter` a struct in the FFI layer

* Add fns for creating a timeline with cache and event type filters

* Remove dead code

* Fix some review comments

* ffi: create new timeline initialization APIs, modify existing ones.
ui: make `Room::timeline()` return `None` if no timeline exists instead of lazily creating one.

More details:

- Added `init_timeline_with_builder` to `matrix_sdk_ui::room_list_service::Room` so a timeline can be initialized at will given a `TimelineBuilder`.
- Create `is_timeline_initialized()` fns in both the ui and ffi layers to check the status of the timeline.
- Make `matrix_sdk_ui::room_list_service::Room::timeline()` only return a timeline if it's already been initialized.
- Create FFI functions to expose these UI ones.

* Fix tests

* Fix some review comments

* Update bindings/matrix-sdk-ffi/src/room_list.rs

Signed-off-by: Benjamin Bouvier <public@benj.me>

---------

Signed-off-by: Benjamin Bouvier <public@benj.me>
Co-authored-by: Benjamin Bouvier <public@benj.me>
2024-01-30 11:00:43 +00:00
Benjamin Bouvier b680c50035 labs: introduce rrrrepl, a client specialized for showing and sending read receipts
This was quite handy during development of the client-side computation of read-receipts, to analyze some bugs.

It might be not useful to have it checked in for long, but I would love to make sure it keeps on compiling
until we have a more stable handling of read receipts in general.
2024-01-22 11:01:26 +01:00
Benjamin Bouvier 55aad67338 Remove the sqlite-lock binary from the main repo
Will move it to a personal repository of mine.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-19 15:42:58 +02:00
Benjamin Bouvier 76ed3511b5
Add a value-based lock in the `CryptoStore`s (#2049)
This implements a value-based lock in the crypto stores. The intent is to use that for multiple processes to be able to make writes into the store concurrently, while still cooperating on who does them. In particular, we need this for #1928, since we may have up to two different processes trying to write into the crypto store at the same time.

## New methods in the `CryptoStore` trait

The idea is to introduce two new methods touching **custom values** in the crypto store:

- one to atomically insert a value, only if it was missing (so, not following the semantics of `upsert` used in the `set_custom_value`) 
- one to atomically remove a custom value

Those two operations match the semantics we want:

- take the lock only if it ain't taken already == insert an entry only if it was missing
- release the lock = remove the entry

By looking at the number of lines affected by the query, we can infer whether the insert/remove happened or not, that is, if we managed to take the lock or not.

## High-level APIs

I've also added an high-level API, `CryptoStoreLock`, that helps managing such a lock, and adds some niceties on top of that:

- exponential backoff to retry attempts at acquiring the lock, when it was already taken
- attempt to gracefully recover when the lock has been taken by an app that's been killed by the environment
- full configuration of the key / value / backoff parameters

While it'd be nice to have something like a `CryptoStoreLockGuard`, it's hard to implement without being racy, because of the `async` statements that would happen in the `Drop` method (and async drop isn't stable yet).

## Test program

There's also a test program in which I shamelessly show my rudimentary unix skills; I've put it in the `labs/` directory but this could as well be a large integration test. A parent program initially fills a custom crypto store, then creates a `pipe()` for 1-way communication with a child created with `fork()`; then the parent sends commands to the child. These commands consist in reading and writing into the crypto store, using a lock. And while the child attempts to perform these operations, the parent tries hard to get the lock at the same time. This helps figuring out a few issues and making sure that cross-process locking would work as intended.
2023-06-16 13:05:54 +00:00
Ivan Enderlin ea5b4c98c1
feat(labs): Remove `jack-in`.
This was a fun ride, but nobody uses it, and we don't need it anymore.

Thanks for all the fishes.
2023-03-30 18:03:38 +02:00
Jonas Platte d680b331d0 Make tokio a workspace dependency 2023-03-28 21:08:57 +02: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
Jonas Platte cc35ee72b8 Upgrade eyeball to 0.4.0 2023-03-11 13:13:50 +01:00
Ivan Enderlin c5d5deba8e
chore: Continue the renaming from view to list for Sliding Sync. 2023-03-01 14:39:09 +01:00
Ivan Enderlin 5377bb7ecf
fix(sdk): Rename `SlidingSyncView` to `SlidingSyncList`.
The specification describes “list”, not “view”. Consistency is important, so
let's rename this type!
2023-03-01 12:09:34 +01:00
Jonas Platte d06e8ccfc5 refactor: Upgrade eyeball and use SharedObservable
… but not in sliding sync yet, where some planned refactorings might
conflict with this.
2023-02-27 13:29:28 +01:00
Jonas Platte d0c8ec7a22 refactor: Replace remaining usage of futures-signal with eyeball(-im) 2023-02-23 15:08:41 +01:00
Jonas Platte 95f1867816 chore: Delete sled-state-inspector
The sled store is on its way out and nobody is using this.
2023-02-22 13:17:01 +01:00
Jonas Platte b96532878b refactor(sdk): Replace futures-signals with eyeball-im in the timeline 2023-02-20 18:01:31 +01:00
Ivan Enderlin 1f3b8048c7
chore(jack-in): Use the latest SS API. 2023-02-20 15:39:23 +01:00
Ivan Enderlin 0f7646ade1 chore: Make Clippy happy. 2023-02-09 16:16:31 +01:00
Ivan Enderlin c6d99305d5 fix(labs): Fix jack-in. 2023-02-09 15:46:08 +01:00
Ivan Enderlin 672a640854 chore(labs): Update to later changes. 2023-02-02 15:27:18 +01:00
Ivan Enderlin 40010cd511 Merge branch 'main' into feat-sliding-sync-view-rooms 2023-02-02 15:26:30 +01:00
Ivan Enderlin a6d33fcd16 feat(labs): Update `jack-in` to the new sliding sync room API. 2023-02-02 15:22:41 +01:00
Jonas Platte 3a1eb62c38 refactor(sdk): Expose event sending errors through timeline item
… instead of through the return value of Timeline::send.
2023-02-02 10:14:23 +01:00
Benjamin Kampmann 9ad34e8565 chore(sliding-sync): update to latest sliding-sync JSON layout 2023-01-31 14:03:43 +00:00
Jonas Platte e066346b16 feat(bindings): Clear the timeline when sliding-sync loop is reset 2023-01-31 11:49:25 +01:00
Jonas Platte 754453c135 refactor: Import tracing macros instead of using qualified paths 2023-01-31 11:49:25 +01:00
Jonas Platte c481caf060 refactor: Clean up format strings 2023-01-31 11:49:25 +01:00
Jonas Platte 6d868908cb refactor(sdk): Remove unused Result 2023-01-31 11:49:25 +01:00
Jonas Platte d2678e2f01 refactor(sdk): Remove unused async 2023-01-31 11:49:25 +01:00
Kévin Commaille 32e7209c66
refactor(sdk): Split room member events between membership and profile change
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-26 14:24:59 +01:00
Kévin Commaille 8cc632ffd1 feat(sdk): Add support for state events in the timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-17 12:10:19 +01:00
Damir Jelić cdfb51a606 refactor!(sdk): Add the experimental prefix to the sliding-sync feature 2023-01-11 11:54:32 +01:00
Jonas Platte 2e30e11101 refactor: Use workspace dependencies for more crates 2023-01-10 10:19:02 +01:00
Marcel Kräml 5852d751bd Updated jack-in README.md for full-sync-mode lowercase options
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2023-01-04 12:38:54 +01:00
Marcel Kräml cda596ebed Changed full_sync_mode to lowercase
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2023-01-04 12:21:14 +01:00
Marcel Kräml eef0bf4b91 Fixed clap for jack-in and update README.md
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2022-12-23 11:29:21 +01:00
Marcel Kräml ad1011ec53 Replace structopt with clap in jack-in
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2022-12-23 11:17:02 +01:00
Kévin Commaille b960c372ac
feat(sdk): Add support for stickers in the timeline 2022-12-19 08:39:07 +00:00
Jonathan de Jong d79c70177b
Lab: The Setup Pattern 2022-12-15 16:48:55 +01:00
Benjamin Kampmann 273d0a0edf
feat(sliding-sync): Growing window and limit count full sync (#1270)
Add a second full-sync-up mode to sliding sync. Previously - and still the default for backwards compatibility, but now named `PagingFullSync` - was to page through the list by the page-size, de-validating the previous page of items. The newly added `GrowingFullSync` instead grows the window by the given number `batch_size` per request, starting and keeping it from `0`. In the latter we might be pushing more data over the connection and are slightly slower, but the top always stays active and thus reactive to changes.

Furthermore the developer can now configure an optional maximum number to grow/paginate the full-sync up to (so stopping before actually having reached `count` whatever is smaller). This is already exposed via FFI, too.

- [x] add new full-sync-mode
- [x] add limited sync-up mode (similar to full sync but only to a limit `n`)
- [x] implement sync-up in jack-in
2022-12-14 13:50:35 +01:00
Kévin Commaille 37bea19ab5
feat(sdk): Add day dividers to the experimental timeline 2022-12-14 12:29:24 +01:00
Benjamin Kampmann 1a0b90291c fix(jack-in): rendering formatting improvements 2022-12-12 15:14:18 +01:00
Benjamin Kampmann 1e4c16b9a9 Merge remote-tracking branch 'origin/main' into ben-update-jack-in 2022-12-07 16:31:32 +01:00
Benjamin Kampmann c4884887ef fix(sliding-sync): set views to preload if we've recovered from frozen 2022-12-07 13:59:50 +00:00