Trying a new recursive BG update task due2 mem limits

This commit is contained in:
Imran Remtulla
2023-08-22 12:51:55 -04:00
parent bb4f34317b
commit e956ee9254
2 changed files with 63 additions and 64 deletions

View File

@@ -71,31 +71,23 @@ Future<void> loadTranslations() async {
fallbackTranslations: controller.fallbackTranslations); fallbackTranslations: controller.fallbackTranslations);
} }
@pragma('vm:entry-point') moveStrToEnd(List<String> arr, String str, {String? strB}) {
Future<void> bgUpdateCheckApps(int taskId, Map<String, dynamic>? params) async { String? temp;
WidgetsFlutterBinding.ensureInitialized(); arr.removeWhere((element) {
await EasyLocalization.ensureInitialized(); bool res = element == str || element == strB;
await AndroidAlarmManager.initialize(); if (res) {
await loadTranslations(); temp = element;
LogsProvider logs = LogsProvider();
AppsProvider appsProvider = AppsProvider();
await appsProvider.loadApps();
logs.add('BG update parent task started.');
var appIds = appsProvider.getAppsSortedByUpdateCheckTime();
for (var id in appIds) {
AndroidAlarmManager.oneShot(
const Duration(minutes: 0), id.hashCode, bgUpdateCheckApp,
params: {'appId': id});
await Future.delayed(const Duration(seconds: 1));
} }
logs.add( return res;
'BG update parent task ended (${appIds.length} child task(s) started).'); });
if (temp != null) {
arr = [...arr, temp!];
}
return arr;
} }
@pragma('vm:entry-point') @pragma('vm:entry-point')
Future<void> bgUpdateCheckApp(int taskId, Map<String, dynamic>? params) async { Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized(); await EasyLocalization.ensureInitialized();
await AndroidAlarmManager.initialize(); await AndroidAlarmManager.initialize();
@@ -104,31 +96,50 @@ Future<void> bgUpdateCheckApp(int taskId, Map<String, dynamic>? params) async {
LogsProvider logs = LogsProvider(); LogsProvider logs = LogsProvider();
NotificationsProvider notificationsProvider = NotificationsProvider(); NotificationsProvider notificationsProvider = NotificationsProvider();
AppsProvider appsProvider = AppsProvider(); AppsProvider appsProvider = AppsProvider();
await appsProvider.loadApps();
String appId = params!['appId'];
params['attemptCount'] = (params['attemptCount'] ?? 0) + 1;
int maxAttempts = 5; int maxAttempts = 5;
params ??= {};
params['attemptCount'] = (params['attemptCount'] ?? 0) + 1;
params['toCheck'] =
params['toCheck'] ?? appsProvider.getAppsSortedByUpdateCheckTime();
params['toInstall'] = params['toInstall'] ?? [];
List<String> toCheck = params['toCheck'];
List<String> toInstall = params['toCheck'];
logs.add( logs.add(
'BG update task for $appId started (attempt #${params['attemptCount']}).'); 'BG update task $taskId started - ${toCheck.length} to check and ${toInstall.length} to install${params['attemptCount'] > 1 ? ' (attempt #${params['attemptCount']})' : ''}.');
try {
await appsProvider.loadApps(singleId: appId); if (toCheck.isNotEmpty) {
AppInMemory app = appsProvider.apps[appId]!; String appId = toCheck.removeAt(0);
App? newApp; AppInMemory? app = appsProvider.apps[appId];
if (app.app.installedVersion == app.app.latestVersion && if (app?.app.installedVersion != null) {
app.app.installedVersion != null) {
try { try {
notificationsProvider.notify(checkingUpdatesNotification, notificationsProvider.notify(checkingUpdatesNotification,
cancelExisting: true); cancelExisting: true);
newApp = await appsProvider.checkUpdate(appId); App? newApp = await appsProvider.checkUpdate(appId);
if (newApp != null) {
if (!(await appsProvider.canInstallSilently(app!.app))) {
notificationsProvider.notify(
UpdateNotification([newApp], id: newApp.id.hashCode * 10));
} else {
toInstall.add(appId);
}
}
} catch (e) { } catch (e) {
logs.add('BG update check for $appId got error \'${e.toString()}\'.'); logs.add(
'BG update check got error on checking for $appId \'${e.toString()}\'.');
if (e is RateLimitError || if (e is RateLimitError ||
e is ClientException && params['attemptCount'] < maxAttempts) { e is ClientException && params['attemptCount'] < maxAttempts) {
var remainingMinutes = e is RateLimitError ? e.remainingMinutes : 15; var remainingMinutes = e is RateLimitError ? e.remainingMinutes : 15;
logs.add( logs.add(
'BG update check for $appId will be retried in $remainingMinutes minutes.'); 'BG update task $taskId will be retried in $remainingMinutes minutes (with $appId moved to the end of the line).');
toCheck = toInstall = []; // So the next task will not start
params['toCheck'] = moveStrToEnd(params['toCheck'], appId);
AndroidAlarmManager.oneShot( AndroidAlarmManager.oneShot(
Duration(minutes: remainingMinutes), taskId, bgUpdateCheckApp, Duration(minutes: remainingMinutes), taskId + 1, bgUpdateCheck,
params: params); params: params);
} else { } else {
rethrow; rethrow;
@@ -137,24 +148,20 @@ Future<void> bgUpdateCheckApp(int taskId, Map<String, dynamic>? params) async {
notificationsProvider.cancel(checkingUpdatesNotification.id); notificationsProvider.cancel(checkingUpdatesNotification.id);
} }
} }
if (newApp != null) { } else if (toInstall.isNotEmpty) {
var canInstallSilently = await appsProvider.canInstallSilently(app.app); toInstall = moveStrToEnd(toInstall, obtainiumId);
if (!canInstallSilently) { String appId = toInstall.removeAt(0);
notificationsProvider
.notify(UpdateNotification([newApp], id: newApp.id.hashCode * 10));
} else {
logs.add('Attempting to update $appId in the background.'); logs.add('Attempting to update $appId in the background.');
await appsProvider.downloadAndInstallLatestApps([appId], null, await appsProvider.downloadAndInstallLatestApps([appId], null,
notificationsProvider: notificationsProvider); notificationsProvider: notificationsProvider);
} }
}
} catch (e) { logs.add('BG update task $taskId ended.');
notificationsProvider.notify(ErrorCheckingUpdatesNotification(
'$appId: ${e.toString()}', if (toCheck.isNotEmpty || toInstall.isNotEmpty) {
id: appId.hashCode * 20)); AndroidAlarmManager.oneShot(Duration(seconds: toCheck.isNotEmpty ? 1 : 5),
} finally { taskId + 1, bgUpdateCheck,
logs.add( params: {'toCheck': toCheck, 'toInstall': toInstall});
'BG update task for $appId ended (attempt #${params['attemptCount']}).');
} }
} }
@@ -254,7 +261,7 @@ class _ObtainiumState extends State<Obtainium> {
AndroidAlarmManager.periodic( AndroidAlarmManager.periodic(
Duration(minutes: existingUpdateInterval), Duration(minutes: existingUpdateInterval),
bgUpdateCheckAlarmId, bgUpdateCheckAlarmId,
bgUpdateCheckApps, bgUpdateCheck,
rescheduleOnReboot: true, rescheduleOnReboot: true,
wakeup: true); wakeup: true);
} }

View File

@@ -15,6 +15,7 @@ import 'package:flutter/services.dart';
import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/main.dart';
import 'package:obtainium/providers/logs_provider.dart'; import 'package:obtainium/providers/logs_provider.dart';
import 'package:obtainium/providers/notifications_provider.dart'; import 'package:obtainium/providers/notifications_provider.dart';
import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/settings_provider.dart';
@@ -555,17 +556,8 @@ class AppsProvider with ChangeNotifier {
List<String> installedIds = []; List<String> installedIds = [];
// Move Obtainium to the end of the line (let all other apps update first) // Move Obtainium to the end of the line (let all other apps update first)
String? temp; appsToInstall =
appsToInstall.removeWhere((element) { moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
bool res = element == obtainiumId || element == obtainiumTempId;
if (res) {
temp = element;
}
return res;
});
if (temp != null) {
appsToInstall = [...appsToInstall, temp!];
}
for (var id in appsToInstall) { for (var id in appsToInstall) {
try { try {