fix(sdk): Introduce SubscribersHandle and SubscriberHandle#6684
Conversation
Even if `AutoSkrinkChannelPayload` is an alias to `OwnedRoomId`, it's still better to use the correct type here in case it changes in the future.
When a cache (from the Event Cache) has no more subscribers, it auto-shrinks to its last chunk to save memory. That's great! The way it counts/tracks the number of subscribers isn't efficient though. It uses an `Arc<AtomicU32>`. `Arc` in itself is already an atomic counter. We can use `Arc<()>` directly, saving the cost of more atomic operations. This patch introduces `SubscribersHandle` that is owned by the cache state (like `RoomEventCacheState`). When a subscriber is created, `SubscribersHandle::new_subscriber_handle` (note the singular form) is called, and produces a `SubscriberHandle` (still singular form). A `SubscriberHandle` is a thin type around `Weak<()>`. The state has an `Arc`, the subscribers have a `Weak`. The number of subscribers is calculated by `(Arc|Weak)::weak_count`. That way, no need to `fetch_add` or `load` to calculate the count. This patch adds a test to ensure the new types are correct and work as expected.
This patch removes the sending of the `VectorDiff`s updates. The documentation said: > Hey, fun stuff: we shrunk the linked chunk, so there shouldn't be any > subscribers, right? RIGHT? Especially because the state is guarded > behind a lock. > > However, better safe than sorry, and it's cheap to send an update > here, so let's do it! I think that's an error. Two situations here: 1. No race, no subscribers have been registered, so it's safe to do nothing, 2. A race, a subscriber has been created meanwhile, we **must not** send the diff to it, otherwise it can create an invalid state.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6684 +/- ##
==========================================
- Coverage 89.88% 89.87% -0.02%
==========================================
Files 396 396
Lines 110264 110307 +43
Branches 110264 110307 +43
==========================================
+ Hits 99115 99142 +27
- Misses 7385 7386 +1
- Partials 3764 3779 +15 ☔ View full report in Codecov by Harness. |
dd316bf to
4347843
Compare
poljar
left a comment
There was a problem hiding this comment.
I think this is mostly fine.
I wonder if we couldn't just use the strong_count() on the auto_shrink_sender() to get the subscriber count.
Also, how come no tests needed to be modified for the last patch? 🙈
Actually, we need to count the number of subscribers, so the
Because I struggle to see how to test it. The auto-shrink happens if and only if no more subscriber exists. How to test nothing is sent if we can't receive it…? Hmm, now I'm giving it a second thought, it might be possible if we write the test at the correct place as a unit test, so that we can have access to the private fields. Let me try. |
This PR is twofold.
When a cache (from the Event Cache) has no more subscribers, it auto-shrinks to its last chunk to save memory. That's great! The way it counts/tracks the number of subscribers isn't efficient though. It uses an
Arc<AtomicU32>.Arcin itself is already an atomic counter. We can useArc<()>directly, saving the cost of more atomic operations.The first main patch introduces
SubscribersHandlethat is owned by the cache state (likeRoomEventCacheState). When a subscriber is created,SubscribersHandle::new_subscriber_handle(note the singular form) is called, and produces aSubscriberHandle(still singular form).A
SubscriberHandleis a thin type aroundWeak<()>. The state has anArc, the subscribers have aWeak. The number of subscribers is calculated by(Arc|Weak)::weak_count. That way, no need tofetch_addorloadto calculate the count.The second main patch removes the sending of the
VectorDiffs updates when the cache is shrunk. The documentation said:I think that's an error. Two situations here:
Note that a race shouldn't be possible as we have acquired an exclusive access to the state, ensuring no subscriber can be created, so technically the diff should be sent to nowhere, but it's really important to not send it :-].
Signed-off-by: