Skip to content

Conversation

@renefloor
Copy link
Collaborator

@renefloor renefloor commented Oct 9, 2025

Submit a pull request

Closes FLU-294
Also fixes FLU-291

Closes #

CLA

  • I have signed the Stream CLA (required).
  • The code changes follow best practices
  • Code changes are tested (add some information if not applicable)

Description of the pull request

The ActivityAdded events don't contain capabilities on the currentFeed, so we have to add them while we get the event and cache the capabilities so we don't have to fetch them often.

Screenshots / Videos

Before After
img img

Copy link

@gpunto gpunto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more or less similar to what I'm implementing, but I have a couple of questions (that I also ask myself)

Comment on lines +37 to +40
Future<List<FeedOwnCapability>?> getCapabilities(String feed) async {
return _capabilities[feed] ??
(await _fetchBatchedFeedCapabilities(feed)).getOrNull();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I read it correctly that on failures we just give up? I'm thinking if it makes sense to have some retry

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, I was not sure yet what to do. Should we just add the list of failed feeds to the next batch, or shall we retry only this specific batch once, so the next batch is clean and can also be retried?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of adding them to the next batch, but no strong opinion. We could also check what they do in JS with @isekovanic

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I've added a retry after half a second, but we can improve on this later

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently I have not added a retry mechanism on JS, but the queued up IDs will simply not be purged unless the request is successful. So they'll be there the next time something arrives.

But, a retry is much better in my opinion as well, since otherwise you might need to wait. I'll add a retry as well on my side.

Comment on lines 37 to 38
final ownCapabilities =
await capabilitiesRepository.getCapabilities(fid.rawValue);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we get another WsEvent while we're waiting here? Is the new event going to be processed concurrently or will it wait until the capabilities call is done (including the debounce timeout)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feed handler can indeed handle multiple concurrent events. This await will only return the capabilities of this feed, but the repository will batch them together.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so just to confirm, if we're waiting here for the backend to respond, we are still going to process other random WS events, like activity deleted, comment added, etc and update the state, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes correct

@renefloor renefloor marked this pull request as ready for review October 15, 2025 10:43
@renefloor renefloor requested a review from a team as a code owner October 15, 2025 10:43
@renefloor renefloor changed the title Add caching for own capabilities feat(llc): Add caching for own capabilities Oct 15, 2025
@codecov
Copy link

codecov bot commented Oct 16, 2025

Codecov Report

❌ Patch coverage is 1.57480% with 125 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.24%. Comparing base (708cdd9) to head (932c516).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ds/lib/src/repository/capabilities_repository.dart 2.77% 35 Missing ⚠️
packages/stream_feeds/lib/src/utils/batcher.dart 0.00% 31 Missing ⚠️
packages/stream_feeds/lib/src/state/feed.dart 0.00% 19 Missing ⚠️
...ages/stream_feeds/lib/src/state/activity_list.dart 0.00% 11 Missing ⚠️
..._feeds/lib/src/state/event/feed_event_handler.dart 0.00% 9 Missing ⚠️
...b/src/state/event/activity_list_event_handler.dart 0.00% 5 Missing ⚠️
...s/lib/src/state/event/feed_capabilities_mixin.dart 0.00% 5 Missing ⚠️
packages/stream_feeds/lib/src/state/activity.dart 0.00% 4 Missing ⚠️
...stream_feeds/lib/src/client/feeds_client_impl.dart 25.00% 3 Missing ⚠️
...ges/stream_feeds/lib/src/models/activity_data.dart 0.00% 3 Missing ⚠️

❌ Your patch status has failed because the patch coverage (1.57%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@           Coverage Diff            @@
##            main     #47      +/-   ##
========================================
- Coverage   3.29%   3.24%   -0.06%     
========================================
  Files        117     120       +3     
  Lines       3157    3271     +114     
========================================
+ Hits         104     106       +2     
- Misses      3053    3165     +112     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +57 to +60
if (result.shouldRetry() && !isRetry) {
await Future<void>.delayed(const Duration(milliseconds: 500));
return _fetchWithRetry(feeds: feeds, isRetry: true);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it going to loop forever in case of no internet? Maybe better to limit it to n times. We can use the backoff from rate_limiter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the isRetry: true we only retry once.

Comment on lines +32 to +39
final activity = event.activity.toModel();
state.onActivityUpdated(activity);

final updatedActivity = await withUpdatedFeedCapabilities(activity);
if (updatedActivity != null) {
state.onActivityUpdated(updatedActivity);
}
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we have this logic in the state layer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed offline to keep it here for now.

@renefloor renefloor merged commit 3295f49 into main Oct 16, 2025
7 of 8 checks passed
@renefloor renefloor deleted the feature/cache-capabilities branch October 16, 2025 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants