Increase isolate pool size to enhance concurrent download capabilities

This commit is contained in:
Moustapha Kodjo Amadou 2026-01-09 11:48:23 +01:00
parent 40fdfc2592
commit 83b7d31e0a
3 changed files with 23 additions and 11 deletions

View file

@ -84,9 +84,7 @@ void main(List<String> args) async {
Future<void> _postLaunchInit(StorageProvider storage) async { Future<void> _postLaunchInit(StorageProvider storage) async {
await AppLogger.init(); await AppLogger.init();
// Initialiser le pool d'Isolates partagé (3 workers) unawaited(MDownloader.initializeIsolatePool(poolSize: 6));
// Optimise la mémoire pour 50+ téléchargements simultanés
unawaited(MDownloader.initializeIsolatePool(poolSize: 3));
final hivePath = (Platform.isIOS || Platform.isMacOS) final hivePath = (Platform.isIOS || Platform.isMacOS)
? "databases" ? "databases"
: p.join("Mangayomi", "databases"); : p.join("Mangayomi", "databases");

View file

@ -24,9 +24,9 @@ class DownloadIsolatePool {
static DownloadIsolatePool? _instance; static DownloadIsolatePool? _instance;
final List<_PoolWorker> _workers = []; final List<_PoolWorker> _workers = [];
final Queue<_DownloadTask> _taskQueue = Queue(); final Queue<_DownloadTask> _taskQueue = Queue();
final Set<int> _availableWorkers = {}; // Track available workers by index
final int poolSize; final int poolSize;
bool _initialized = false; bool _initialized = false;
int _activeWorkers = 0;
DownloadIsolatePool._({this.poolSize = 3}); DownloadIsolatePool._({this.poolSize = 3});
@ -58,6 +58,7 @@ class DownloadIsolatePool {
for (int i = 0; i < poolSize; i++) { for (int i = 0; i < poolSize; i++) {
final worker = await _PoolWorker.create(i); final worker = await _PoolWorker.create(i);
_workers.add(worker); _workers.add(worker);
_availableWorkers.add(i); // All workers start as available
} }
_initialized = true; _initialized = true;
@ -187,13 +188,25 @@ class DownloadIsolatePool {
/// Process the task queue /// Process the task queue
void _processQueue() { void _processQueue() {
while (_taskQueue.isNotEmpty && _activeWorkers < _workers.length) { while (_taskQueue.isNotEmpty && _availableWorkers.isNotEmpty) {
final task = _taskQueue.removeFirst(); final task = _taskQueue.removeFirst();
final worker = _workers[_activeWorkers]; final workerIndex = _availableWorkers.first;
_activeWorkers++; _availableWorkers.remove(workerIndex);
final worker = _workers[workerIndex];
if (kDebugMode) {
print(
'[DownloadPool] Worker $workerIndex starting task ${task.taskId}',
);
}
worker.executeTask(task).then((_) { worker.executeTask(task).then((_) {
_activeWorkers--; _availableWorkers.add(workerIndex); // Worker is free again
if (kDebugMode) {
print(
'[DownloadPool] Worker $workerIndex finished task ${task.taskId}, available workers: ${_availableWorkers.length}',
);
}
_processQueue(); // Process the next task _processQueue(); // Process the next task
}); });
} }
@ -203,7 +216,7 @@ class DownloadIsolatePool {
int get pendingTasks => _taskQueue.length; int get pendingTasks => _taskQueue.length;
/// Number of active workers /// Number of active workers
int get activeWorkers => _activeWorkers; int get activeWorkers => poolSize - _availableWorkers.length;
/// Close the pool /// Close the pool
void dispose() { void dispose() {
@ -212,9 +225,9 @@ class DownloadIsolatePool {
} }
_workers.clear(); _workers.clear();
_taskQueue.clear(); _taskQueue.clear();
_availableWorkers.clear();
downloadTaskCancellation.clear(); downloadTaskCancellation.clear();
_initialized = false; _initialized = false;
_activeWorkers = 0;
} }
} }

View file

@ -43,7 +43,8 @@ class MDownloader {
} }
/// Initialize the Isolate pool (call once at app startup) /// Initialize the Isolate pool (call once at app startup)
static Future<void> initializeIsolatePool({int poolSize = 3}) async { /// poolSize = 6 workers allows 6 chapters to download in parallel
static Future<void> initializeIsolatePool({int poolSize = 6}) async {
DownloadIsolatePool.configure(poolSize: poolSize); DownloadIsolatePool.configure(poolSize: poolSize);
await DownloadIsolatePool.instance.initialize(); await DownloadIsolatePool.instance.initialize();
} }