diff --git a/mobile/lib/domain/services/background_worker.service.dart b/mobile/lib/domain/services/background_worker.service.dart index 50f9f99191..90e2ddff4c 100644 --- a/mobile/lib/domain/services/background_worker.service.dart +++ b/mobile/lib/domain/services/background_worker.service.dart @@ -7,6 +7,8 @@ import 'package:cancellation_token_http/http.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/constants.dart'; +import 'package:immich_mobile/domain/services/log.service.dart'; +import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/network_capability_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/generated/intl_keys.g.dart'; @@ -27,11 +29,11 @@ import 'package:immich_mobile/services/localization.service.dart'; import 'package:immich_mobile/services/server_info.service.dart'; import 'package:immich_mobile/services/upload.service.dart'; import 'package:immich_mobile/utils/bootstrap.dart'; +import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/http_ssl_options.dart'; import 'package:isar/isar.dart'; import 'package:logging/logging.dart'; import 'package:worker_manager/worker_manager.dart'; -import 'package:immich_mobile/utils/debug_print.dart'; class BackgroundWorkerFgService { final BackgroundWorkerFgHostApi _foregroundHostApi; @@ -181,6 +183,8 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { // Discard any errors on the dispose call return; }), + LogService.I.dispose(), + Store.dispose(), _drift.close(), _driftLogger.close(), backgroundSyncManager.cancel(), @@ -269,6 +273,6 @@ Future backgroundSyncNativeEntrypoint() async { DartPluginRegistrant.ensureInitialized(); final (isar, drift, logDB) = await Bootstrap.initDB(); - await Bootstrap.initDomain(isar, drift, logDB, shouldBufferLogs: false); + await Bootstrap.initDomain(isar, drift, logDB, shouldBufferLogs: false, listenStoreUpdates: false); await BackgroundWorkerBgService(isar: isar, drift: drift, driftLogger: logDB).init(); } diff --git a/mobile/lib/domain/services/store.service.dart b/mobile/lib/domain/services/store.service.dart index 762d5db3b9..f9b4a0aa81 100644 --- a/mobile/lib/domain/services/store.service.dart +++ b/mobile/lib/domain/services/store.service.dart @@ -10,7 +10,7 @@ class StoreService { /// In-memory cache. Keys are [StoreKey.id] final Map _cache = {}; - late final StreamSubscription> _storeUpdateSubscription; + StreamSubscription>? _storeUpdateSubscription; StoreService._({required IStoreRepository isarStoreRepository}) : _storeRepository = isarStoreRepository; @@ -24,15 +24,17 @@ class StoreService { } // TODO: Replace the implementation with the one from create after removing the typedef - static Future init({required IStoreRepository storeRepository}) async { - _instance ??= await create(storeRepository: storeRepository); + static Future init({required IStoreRepository storeRepository, bool listenUpdates = true}) async { + _instance ??= await create(storeRepository: storeRepository, listenUpdates: listenUpdates); return _instance!; } - static Future create({required IStoreRepository storeRepository}) async { + static Future create({required IStoreRepository storeRepository, bool listenUpdates = true}) async { final instance = StoreService._(isarStoreRepository: storeRepository); await instance.populateCache(); - instance._storeUpdateSubscription = instance._listenForChange(); + if (listenUpdates) { + instance._storeUpdateSubscription = instance._listenForChange(); + } return instance; } @@ -50,8 +52,8 @@ class StoreService { }); /// Disposes the store and cancels the subscription. To reuse the store call init() again - void dispose() async { - await _storeUpdateSubscription.cancel(); + Future dispose() async { + await _storeUpdateSubscription?.cancel(); _cache.clear(); } diff --git a/mobile/lib/services/background.service.dart b/mobile/lib/services/background.service.dart index 39620c17fb..33a8e810f1 100644 --- a/mobile/lib/services/background.service.dart +++ b/mobile/lib/services/background.service.dart @@ -28,11 +28,11 @@ import 'package:immich_mobile/services/backup.service.dart'; import 'package:immich_mobile/services/localization.service.dart'; import 'package:immich_mobile/utils/backup_progress.dart'; import 'package:immich_mobile/utils/bootstrap.dart'; +import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/diff.dart'; import 'package:immich_mobile/utils/http_ssl_options.dart'; import 'package:path_provider_foundation/path_provider_foundation.dart'; import 'package:photo_manager/photo_manager.dart' show PMProgressHandler; -import 'package:immich_mobile/utils/debug_print.dart'; final backgroundServiceProvider = Provider((ref) => BackgroundService()); @@ -331,7 +331,7 @@ class BackgroundService { Future _onAssetsChanged() async { final (isar, drift, logDb) = await Bootstrap.initDB(); - await Bootstrap.initDomain(isar, drift, logDb); + await Bootstrap.initDomain(isar, drift, logDb, shouldBufferLogs: false, listenStoreUpdates: false); final ref = ProviderContainer( overrides: [ diff --git a/mobile/lib/utils/bootstrap.dart b/mobile/lib/utils/bootstrap.dart index c7d7cb8192..c77ceaa62d 100644 --- a/mobile/lib/utils/bootstrap.dart +++ b/mobile/lib/utils/bootstrap.dart @@ -89,11 +89,17 @@ abstract final class Bootstrap { return (isar, drift, logDb); } - static Future initDomain(Isar db, Drift drift, DriftLogger logDb, {bool shouldBufferLogs = true}) async { + static Future initDomain( + Isar db, + Drift drift, + DriftLogger logDb, { + bool listenStoreUpdates = true, + bool shouldBufferLogs = true, + }) async { final isBeta = await IsarStoreRepository(db).tryGet(StoreKey.betaTimeline) ?? true; final IStoreRepository storeRepo = isBeta ? DriftStoreRepository(drift) : IsarStoreRepository(db); - await StoreService.init(storeRepository: storeRepo); + await StoreService.init(storeRepository: storeRepo, listenUpdates: listenStoreUpdates); await LogService.init( logRepository: LogRepository(logDb), diff --git a/mobile/lib/utils/isolate.dart b/mobile/lib/utils/isolate.dart index 0d66d54a09..e8b7d410f4 100644 --- a/mobile/lib/utils/isolate.dart +++ b/mobile/lib/utils/isolate.dart @@ -4,14 +4,15 @@ import 'dart:ui'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; +import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/providers/infrastructure/cancel.provider.dart'; import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; import 'package:immich_mobile/utils/bootstrap.dart'; +import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/http_ssl_options.dart'; import 'package:logging/logging.dart'; import 'package:worker_manager/worker_manager.dart'; -import 'package:immich_mobile/utils/debug_print.dart'; class InvalidIsolateUsageException implements Exception { const InvalidIsolateUsageException(); @@ -37,7 +38,7 @@ Cancelable runInIsolateGentle({ DartPluginRegistrant.ensureInitialized(); final (isar, drift, logDb) = await Bootstrap.initDB(); - await Bootstrap.initDomain(isar, drift, logDb, shouldBufferLogs: false); + await Bootstrap.initDomain(isar, drift, logDb, shouldBufferLogs: false, listenStoreUpdates: false); final ref = ProviderContainer( overrides: [ // TODO: Remove once isar is removed @@ -61,6 +62,7 @@ Cancelable runInIsolateGentle({ try { ref.dispose(); + await Store.dispose(); await LogService.I.dispose(); await logDb.close(); await drift.close();