Skip to content

fix: timeline service uninitialised across routes #19544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2025

Conversation

shenlong-tanwen
Copy link
Member

Description

Using a ProviderScope to override the timelineService for a particular sub-tree works for most cases except when we need access to the overridden service in other sub-trees like from the parent / across routes. It is addressed by making the service always initialised with the main timeline segments.

Whenever a new route with a timeline is pushed, we've to now update the global service provider to use the buckets for the new route. The new route will revert the provider to the main timeline segments before being disposed

Comment on lines 27 to 49
@override
TimelineService build() {
final timelineUsers = ref.watch(timelineUsersIdsProvider);
final service = TimelineService(
assetSource: (offset, count) => _timelineRepository
.getMainBucketAssets(timelineUsers, offset: offset, count: count),
bucketSource: () =>
_timelineRepository.watchMainBucket(timelineUsers, groupBy: groupBy),
);
ref.onDispose(service.dispose);
return service;
}

void localAlbum({required String albumId}) {
final service = TimelineService(
assetSource: (offset, count) => _timelineRepository
.getLocalBucketAssets(albumId, offset: offset, count: count),
bucketSource: () =>
_timelineRepository.watchLocalBucket(albumId, groupBy: groupBy),
);
ref.onDispose(service.dispose);
state = service;
}
Copy link
Member

Choose a reason for hiding this comment

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

Is there a particular reason these create a new service every time?

Also, the assetSource and bucketSource seem odd to me. Shouldn't the service be the one interacting with the repositories?

Copy link
Member Author

Choose a reason for hiding this comment

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

Is there a particular reason these create a new service every time?

Yes, we use an internal buffer inside the service to preload assets when being scrolled. So when the timeline changes, we drop the older service and create a new one, essentially resetting everything.

Also, the assetSource and bucketSource seem odd to me. Shouldn't the service be the one interacting with the repositories?

The service is still the one that interacts with the repositories, yes. But since each timeline requires a different number of parameters, I've handled it by abstracting the service to rely on the following two methods instead:

typedef TimelineAssetSource = Future<List<BaseAsset>> Function(
  int index,
  int count,
);

typedef TimelineBucketSource = Stream<List<Bucket>> Function();

Now, based on the timeline being viewed, we pass in a closure to the service that resolves the other additional arguments.

Copy link
Member

@mertalev mertalev Jul 1, 2025

Choose a reason for hiding this comment

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

Perhaps a broader discussion, but are we sure that the buffer is actually beneficial? SQLite already caches pages in-memory (relevant pragma), unlike Isar which only relies on OS-level paging. If we need to reset this buffer or store multiple buffers in memory (doing power of two allocations for the lists each time), then scan these buffers in Dart, etc., it makes me wonder if this is actually better than what SQLite is doing.

@shenlong-tanwen shenlong-tanwen force-pushed the fix/timeline-service-scope branch from 7bb5abc to 5e9e864 Compare June 26, 2025 14:24
@shenlong-tanwen shenlong-tanwen force-pushed the fix/timeline-service-scope branch from 5e9e864 to 704c77c Compare July 1, 2025 11:28
@alextran1502 alextran1502 merged commit 15be343 into main Jul 1, 2025
47 checks passed
@alextran1502 alextran1502 deleted the fix/timeline-service-scope branch July 1, 2025 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants