fix(sdk): Remove a cyclic reference of Client in ThreadSubscriptionCatchup#6594
Conversation
…nCatchup`. This patch fixes cyclic reference of `Client` in `ThreadSubscriptionCatchup`. `ThreadSubscriptionCatchup` starts a task that call `thread_subscriptions_catchup_task`. This function captures a clone of `ThreadSubscriptionCatchup` (why not…) which contains a `WeakClient`, all good, no cycle here! However, the real task (not the function) captures `Client` to call `enabled_thread_subscriptions` to know if the function `thread_subscriptions_catchup_task` must be called. Consequently, the task captures a clone of `Client`, boom, we have a cycle. This patch fixes the problem by spawning the task if and only if `Client::enabled_thread_subscriptions` returns `Ok(true)`. This check is done outside the task. It seems saner and avoid creating this cycle. Consequently, the `ThreadSubscriptionCatchup::new` method becomes `async`, which is perfectly fine as it was already wrapper inside an `async` block when initialised by the `Client`.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6594 +/- ##
==========================================
- Coverage 89.96% 89.95% -0.01%
==========================================
Files 382 382
Lines 107797 107810 +13
Branches 107797 107810 +13
==========================================
+ Hits 96979 96982 +3
- Misses 7153 7160 +7
- Partials 3665 3668 +3 ☔ View full report in Codecov by Sentry. |
poljar
left a comment
There was a problem hiding this comment.
A bit annoying that we added a test-only field, though it seems to me that we can get rid of it.
|
|
||
| #[cfg(test)] | ||
| task_is_running: AtomicBool, |
There was a problem hiding this comment.
Is this needed? Can't you use OnceCell::initialized() on the thread_subscription_catchup field for this?
There was a problem hiding this comment.
We are using OnceLock, not OnceCell, which also has an initialized method, but it's private! I've changed for tsc._task.get().is_some() and it works nicely.
Thanks for noticing this!
Rebasing and merging.
…readSubscriptionCatchup`.
This patch fixes cyclic reference of
ClientinThreadSubscriptionCatchup.ThreadSubscriptionCatchupstarts a task that callthread_subscriptions_catchup_task. This function captures a clone ofThreadSubscriptionCatchup(why not…) which contains aWeakClient, all good, no cycle here! However, the real task (not the function) capturesClientto callenabled_thread_subscriptionsto know if the functionthread_subscriptions_catchup_taskmust be called. Consequently, the task captures a clone ofClient, boom, we have a cycle.This patch fixes the problem by spawning the task if and only if
Client::enabled_thread_subscriptionsreturnsOk(true). This check is done outside the task. It seems saner and avoid creating this cycle.Consequently, the
ThreadSubscriptionCatchup::newmethod becomesasync, which is perfectly fine as it was already wrapper inside anasyncblock when initialised by theClient.Without the fix, the test fails with:
as expected.
Arc<ClientInner>reference cycle viaThreadSubscriptionCatchuppreventsClientdrop inmatrix-sdk0.17.0 #6573(see Writing changelog entries).