mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-23 01:06:21 +01:00
Run startup sync in background isolate
This commit is contained in:
parent
49b5901149
commit
3387378181
6 changed files with 127 additions and 16 deletions
|
@ -39,7 +39,10 @@ import 'package:visibility_detector/visibility_detector.dart';
|
||||||
|
|
||||||
enum InitIsolateType {
|
enum InitIsolateType {
|
||||||
main,
|
main,
|
||||||
service,
|
|
||||||
|
/// Isolates with Flutter engine, e.g., those spawned by flutter_isolate or
|
||||||
|
/// flutter_background_service
|
||||||
|
flutterIsolate,
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> init(InitIsolateType isolateType) async {
|
Future<void> init(InitIsolateType isolateType) async {
|
||||||
|
@ -200,7 +203,7 @@ Future<sql.SqliteDb> _createDb(InitIsolateType isolateType) async {
|
||||||
return sql_isolate.createDb();
|
return sql_isolate.createDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
case InitIsolateType.service:
|
case InitIsolateType.flutterIsolate:
|
||||||
// service already runs in an isolate
|
// service already runs in an isolate
|
||||||
return sql.SqliteDb();
|
return sql.SqliteDb();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ class _Service {
|
||||||
final service = FlutterBackgroundService();
|
final service = FlutterBackgroundService();
|
||||||
service.setForegroundMode(true);
|
service.setForegroundMode(true);
|
||||||
|
|
||||||
await app_init.init(app_init.InitIsolateType.service);
|
await app_init.init(app_init.InitIsolateType.flutterIsolate);
|
||||||
await _L10n().init();
|
await _L10n().init();
|
||||||
|
|
||||||
_log.info("[call] Service started");
|
_log.info("[call] Service started");
|
||||||
|
|
104
app/lib/use_case/startup_sync.dart
Normal file
104
app/lib/use_case/startup_sync.dart
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:event_bus/event_bus.dart';
|
||||||
|
import 'package:flutter_isolate/flutter_isolate.dart';
|
||||||
|
import 'package:kiwi/kiwi.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:nc_photos/account.dart';
|
||||||
|
import 'package:nc_photos/app_init.dart' as app_init;
|
||||||
|
import 'package:nc_photos/di_container.dart';
|
||||||
|
import 'package:nc_photos/event/event.dart';
|
||||||
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
|
import 'package:nc_photos/type.dart';
|
||||||
|
import 'package:nc_photos/use_case/sync_favorite.dart';
|
||||||
|
|
||||||
|
/// Sync various properties with server during startup
|
||||||
|
class StartupSync {
|
||||||
|
StartupSync(this._c)
|
||||||
|
: assert(require(_c)),
|
||||||
|
assert(SyncFavorite.require(_c));
|
||||||
|
|
||||||
|
static bool require(DiContainer c) => true;
|
||||||
|
|
||||||
|
/// Sync in a background isolate
|
||||||
|
static Future<SyncResult> runInIsolate(Account account) async {
|
||||||
|
if (platform_k.isWeb) {
|
||||||
|
// not supported on web
|
||||||
|
final c = KiwiContainer().resolve<DiContainer>();
|
||||||
|
return await StartupSync(c)(account);
|
||||||
|
} else {
|
||||||
|
// we can't use regular isolate here because self-signed cert support
|
||||||
|
// requires native plugins
|
||||||
|
final resultJson =
|
||||||
|
await flutterCompute(_isolateMain, _IsolateMessage(account).toJson());
|
||||||
|
final result = SyncResult.fromJson(resultJson);
|
||||||
|
// events fired in background isolate won't be noticed by the main isolate,
|
||||||
|
// so we fire them again here
|
||||||
|
_broadcastResult(account, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SyncResult> call(Account account) async {
|
||||||
|
_log.info("[_run] Begin sync");
|
||||||
|
late final int syncFavoriteCount;
|
||||||
|
try {
|
||||||
|
syncFavoriteCount = await SyncFavorite(_c)(account);
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
_log.shout("[_run] Failed while SyncFavorite", e, stackTrace);
|
||||||
|
syncFavoriteCount = -1;
|
||||||
|
}
|
||||||
|
return SyncResult(syncFavoriteCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _broadcastResult(Account account, SyncResult result) {
|
||||||
|
final eventBus = KiwiContainer().resolve<EventBus>();
|
||||||
|
if (result.syncFavoriteCount > 0) {
|
||||||
|
eventBus.fire(FavoriteResyncedEvent(account));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final DiContainer _c;
|
||||||
|
|
||||||
|
static final _log = Logger("use_case.startup_sync.StartupSync");
|
||||||
|
}
|
||||||
|
|
||||||
|
class SyncResult {
|
||||||
|
const SyncResult(this.syncFavoriteCount);
|
||||||
|
|
||||||
|
factory SyncResult.fromJson(JsonObj json) => SyncResult(
|
||||||
|
json["syncFavoriteCount"],
|
||||||
|
);
|
||||||
|
|
||||||
|
JsonObj toJson() => {
|
||||||
|
"syncFavoriteCount": syncFavoriteCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
final int syncFavoriteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IsolateMessage {
|
||||||
|
const _IsolateMessage(this.account);
|
||||||
|
|
||||||
|
factory _IsolateMessage.fromJson(JsonObj json) => _IsolateMessage(
|
||||||
|
Account.fromJson(
|
||||||
|
json["account"].cast<String, dynamic>(),
|
||||||
|
upgraderV1: const AccountUpgraderV1(),
|
||||||
|
)!,
|
||||||
|
);
|
||||||
|
|
||||||
|
JsonObj toJson() => {
|
||||||
|
"account": account.toJson(),
|
||||||
|
};
|
||||||
|
|
||||||
|
final Account account;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<JsonObj> _isolateMain(JsonObj messageJson) async {
|
||||||
|
final message = _IsolateMessage.fromJson(messageJson);
|
||||||
|
await app_init.init(app_init.InitIsolateType.flutterIsolate);
|
||||||
|
|
||||||
|
final c = KiwiContainer().resolve<DiContainer>();
|
||||||
|
final result = await StartupSync(c)(message.account);
|
||||||
|
return result.toJson();
|
||||||
|
}
|
|
@ -21,7 +21,6 @@ import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/event/event.dart';
|
import 'package:nc_photos/event/event.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/language_util.dart' as language_util;
|
import 'package:nc_photos/language_util.dart' as language_util;
|
||||||
|
@ -35,7 +34,7 @@ import 'package:nc_photos/share_handler.dart';
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/throttler.dart';
|
import 'package:nc_photos/throttler.dart';
|
||||||
import 'package:nc_photos/use_case/sync_favorite.dart';
|
import 'package:nc_photos/use_case/startup_sync.dart';
|
||||||
import 'package:nc_photos/widget/album_browser_util.dart' as album_browser_util;
|
import 'package:nc_photos/widget/album_browser_util.dart' as album_browser_util;
|
||||||
import 'package:nc_photos/widget/builder/photo_list_item_builder.dart';
|
import 'package:nc_photos/widget/builder/photo_list_item_builder.dart';
|
||||||
import 'package:nc_photos/widget/handler/add_selection_to_album_handler.dart';
|
import 'package:nc_photos/widget/handler/add_selection_to_album_handler.dart';
|
||||||
|
@ -381,7 +380,7 @@ class _HomePhotosState extends State<HomePhotos>
|
||||||
state is ScanAccountDirBlocLoading) {
|
state is ScanAccountDirBlocLoading) {
|
||||||
_transformItems(state.files);
|
_transformItems(state.files);
|
||||||
if (state is ScanAccountDirBlocSuccess) {
|
if (state is ScanAccountDirBlocSuccess) {
|
||||||
_syncFavorite();
|
_startupSync();
|
||||||
_tryStartMetadataTask();
|
_tryStartMetadataTask();
|
||||||
}
|
}
|
||||||
} else if (state is ScanAccountDirBlocFailure) {
|
} else if (state is ScanAccountDirBlocFailure) {
|
||||||
|
@ -536,18 +535,10 @@ class _HomePhotosState extends State<HomePhotos>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _syncFavorite() async {
|
Future<void> _startupSync() async {
|
||||||
if (!_hasResyncedFavorites.value) {
|
if (!_hasResyncedFavorites.value) {
|
||||||
final c = KiwiContainer().resolve<DiContainer>();
|
|
||||||
try {
|
|
||||||
await SyncFavorite(c)(widget.account);
|
|
||||||
} catch (e, stackTrace) {
|
|
||||||
if (e is! ApiException) {
|
|
||||||
_log.shout(
|
|
||||||
"[_syncFavorite] Failed while SyncFavorite", e, stackTrace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_hasResyncedFavorites.value = true;
|
_hasResyncedFavorites.value = true;
|
||||||
|
StartupSync.runInIsolate(widget.account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,6 +490,15 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.0"
|
version: "3.3.0"
|
||||||
|
flutter_isolate:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: "2.0.2-nc-photos-1"
|
||||||
|
resolved-ref: "8d8516b169860caba762baed43a7888798c5b7d7"
|
||||||
|
url: "https://gitlab.com/nc-photos/flutter_isolate.git"
|
||||||
|
source: git
|
||||||
|
version: "2.0.2"
|
||||||
flutter_keyboard_visibility:
|
flutter_keyboard_visibility:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -57,6 +57,10 @@ dependencies:
|
||||||
url: https://gitlab.com/nc-photos/flutter_background_service.git
|
url: https://gitlab.com/nc-photos/flutter_background_service.git
|
||||||
ref: v0.2.6-nc-photos-2
|
ref: v0.2.6-nc-photos-2
|
||||||
flutter_bloc: ^8.0.0
|
flutter_bloc: ^8.0.0
|
||||||
|
flutter_isolate:
|
||||||
|
git:
|
||||||
|
url: https://gitlab.com/nc-photos/flutter_isolate.git
|
||||||
|
ref: 2.0.2-nc-photos-1
|
||||||
flutter_map: ^1.1.1
|
flutter_map: ^1.1.1
|
||||||
flutter_staggered_grid_view:
|
flutter_staggered_grid_view:
|
||||||
git:
|
git:
|
||||||
|
|
Loading…
Reference in a new issue