use asynccache

This commit is contained in:
shenlong-tanwen 2024-11-24 22:32:21 +05:30
parent 8450c8cc4f
commit 0e8b19e269
8 changed files with 35 additions and 23 deletions

View File

@ -11,13 +11,8 @@ class UserApiRepository with LogMixin implements IUserApiRepository {
@override @override
Future<model.User?> getMyUser() async { Future<model.User?> getMyUser() async {
try { try {
final [ final (userDto, preferencesDto) =
userDto as UserAdminResponseDto?, await (_usersApi.getMyUser(), _usersApi.getMyPreferences()).wait;
preferencesDto as UserPreferencesResponseDto?
] = await Future.wait([
_usersApi.getMyUser(),
_usersApi.getMyPreferences(),
]);
if (userDto == null) { if (userDto == null) {
log.e("Cannot fetch my user."); log.e("Cannot fetch my user.");

View File

@ -1,3 +1,4 @@
import 'package:async/async.dart';
import 'package:immich_mobile/domain/interfaces/album.interface.dart'; import 'package:immich_mobile/domain/interfaces/album.interface.dart';
import 'package:immich_mobile/domain/interfaces/album_asset.interface.dart'; import 'package:immich_mobile/domain/interfaces/album_asset.interface.dart';
import 'package:immich_mobile/domain/interfaces/album_etag.interface.dart'; import 'package:immich_mobile/domain/interfaces/album_etag.interface.dart';
@ -14,10 +15,13 @@ import 'package:immich_mobile/utils/isolate_helper.dart';
import 'package:immich_mobile/utils/mixins/log.mixin.dart'; import 'package:immich_mobile/utils/mixins/log.mixin.dart';
class AlbumSyncService with LogMixin { class AlbumSyncService with LogMixin {
const AlbumSyncService(); AlbumSyncService();
final _fullDeviceSyncCache = AsyncCache<bool>.ephemeral();
Future<bool> performFullDeviceSyncIsolate() async { Future<bool> performFullDeviceSyncIsolate() async {
return await IsolateHelper.run(performFullDeviceSync); return await _fullDeviceSyncCache
.fetch(() async => await IsolateHelper.run(performFullDeviceSync));
} }
Future<bool> performFullDeviceSync() async { Future<bool> performFullDeviceSync() async {

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:async/async.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:immich_mobile/domain/interfaces/api/sync_api.interface.dart'; import 'package:immich_mobile/domain/interfaces/api/sync_api.interface.dart';
import 'package:immich_mobile/domain/interfaces/asset.interface.dart'; import 'package:immich_mobile/domain/interfaces/asset.interface.dart';
@ -13,20 +14,24 @@ import 'package:immich_mobile/utils/isolate_helper.dart';
import 'package:immich_mobile/utils/mixins/log.mixin.dart'; import 'package:immich_mobile/utils/mixins/log.mixin.dart';
class AssetSyncService with LogMixin { class AssetSyncService with LogMixin {
const AssetSyncService(); AssetSyncService();
final _fullRemoteSyncCache = AsyncCache<bool>.ephemeral();
Future<bool> performFullRemoteSyncIsolate( Future<bool> performFullRemoteSyncIsolate(
User user, { User user, {
DateTime? updatedUtil, DateTime? updatedUtil,
int? limit, int? limit,
}) async { }) async {
return await IsolateHelper.run(() async { return await _fullRemoteSyncCache.fetch(
() async => await IsolateHelper.run(() async {
return await performFullRemoteSync( return await performFullRemoteSync(
user, user,
updatedUtil: updatedUtil, updatedUtil: updatedUtil,
limit: limit, limit: limit,
); );
}); }),
);
} }
Future<bool> performFullRemoteSync( Future<bool> performFullRemoteSync(

View File

@ -1,8 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart'; import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:immich_mobile/domain/interfaces/album.interface.dart'; import 'package:immich_mobile/domain/interfaces/album.interface.dart';
@ -22,6 +20,7 @@ import 'package:immich_mobile/presentation/states/gallery_permission.state.dart'
import 'package:immich_mobile/presentation/states/server_info.state.dart'; import 'package:immich_mobile/presentation/states/server_info.state.dart';
import 'package:immich_mobile/service_locator.dart'; import 'package:immich_mobile/service_locator.dart';
import 'package:immich_mobile/utils/immich_api_client.dart'; import 'package:immich_mobile/utils/immich_api_client.dart';
import 'package:immich_mobile/utils/isolate_helper.dart';
import 'package:immich_mobile/utils/mixins/log.mixin.dart'; import 'package:immich_mobile/utils/mixins/log.mixin.dart';
// Cannot add dependency repos to constructor as this requires the newly registered API client from login // Cannot add dependency repos to constructor as this requires the newly registered API client from login
@ -59,7 +58,7 @@ class LoginService with LogMixin {
); );
if (res.statusCode == HttpStatus.ok) { if (res.statusCode == HttpStatus.ok) {
final data = await compute(jsonDecode, res.body); final data = await IsolateHelper.decodeJson(res.bodyBytes);
final endpoint = data['api']['endpoint'].toString(); final endpoint = data['api']['endpoint'].toString();
// Full URL is relative to base // Full URL is relative to base

View File

@ -12,7 +12,7 @@ class ServerInfoProvider extends ValueNotifier<ServerInfo> {
super(const ServerInfo.initial()); super(const ServerInfo.initial());
Future<void> fetchFeatures() async => Future<void> fetchFeatures() async =>
await Future.wait([_getFeatures(), _getConfig(), _getVersion()]); await (_getFeatures(), _getConfig(), _getVersion()).wait;
Future<void> _getFeatures() async { Future<void> _getFeatures() async {
final features = await _serverApiRepository.getServerFeatures(); final features = await _serverApiRepository.getServerFeatures();

View File

@ -138,8 +138,8 @@ abstract final class ServiceLocator {
static void _registerServices() { static void _registerServices() {
/// Special services. So they are initiated as singletons /// Special services. So they are initiated as singletons
_registerSingleton(ImHostService()); _registerSingleton(ImHostService());
_registerSingleton(const AlbumSyncService()); _registerSingleton(AlbumSyncService());
_registerSingleton(const AssetSyncService()); _registerSingleton(AssetSyncService());
/// ///
_registerFactory<LoginService>(() => const LoginService()); _registerFactory<LoginService>(() => const LoginService());

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:isolate'; import 'dart:isolate';
import 'dart:ui'; import 'dart:ui';
@ -82,4 +83,11 @@ class IsolateHelper {
} }
}); });
} }
static Future<Map<String, dynamic>> decodeJson(Uint8List json) async {
return await Isolate.run(
() => const Utf8Decoder().fuse(const JsonDecoder()).convert(json)
as Map<String, dynamic>,
);
}
} }

View File

@ -36,6 +36,7 @@ dependencies:
logging: ^1.3.0 logging: ^1.3.0
# Collection Utils # Collection Utils
collection: ^1.18.0 collection: ^1.18.0
async: ^2.12.0
# service_locator # service_locator
get_it: ^8.0.0 get_it: ^8.0.0
# Photo Manager # Photo Manager