concurrent method

Future<void> concurrent(
  1. DownloadTask task,
  2. Map<String, String> headers,
  3. int contentLength
)

Manages concurrent download tasks.

Ensures that no more than 3 concurrent downloads are active for the same URL. If the number of concurrent downloads is less than 3, creates and adds new tasks.

Implementation

Future<void> concurrent(
  DownloadTask task,
  Map<String, String> headers,
  int contentLength,
) async {
  DownloadTask newTask = task;
  int activeSize = VideoProxy.downloadManager.allTasks
      .where((e) => e.url == newTask.url)
      .length;
  while (activeSize < 2) {
    final nextStartRange = newTask.startRange + Config.segmentSize;
    // Bail when the total length is unknown (head failed) or the next segment
    // would start past EOF. Without the `contentLength <= 0` guard a failed
    // head leaves no upper bound, so an all-cached tail spins this loop
    // forever (activeSize never grows, nextStartRange never terminates).
    if (contentLength <= 0 || nextStartRange >= contentLength) return;
    // Clamp the last warmed segment to the real file boundary. Some servers
    // reject over-wide byte ranges, which can leave a "preloaded" tail
    // segment missing.
    newTask = DownloadTask(
      uri: newTask.uri,
      startRange: nextStartRange,
      endRange: _segmentEndRange(nextStartRange, contentLength),
      headers: headers,
    );
    bool isExit = VideoProxy.downloadManager.allTasks
        .where((e) => e.matchUrl == newTask.matchUrl)
        .isNotEmpty;
    Uint8List? dataMemory = await LruCacheSingleton().memoryGet(
      newTask.matchUrl,
    );
    if (dataMemory != null) isExit = true;
    newTask.cacheDir = await FileExt.createCachePath(newTask.uri.generateMd5);
    File file = File(newTask.savePath);
    if (file.existsSync()) isExit = true;
    if (isExit) continue;
    logD("Asynchronous download start: ${newTask.toString()}");
    await VideoProxy.downloadManager.executeTask(newTask);
    activeSize = VideoProxy.downloadManager.allTasks
        .where((e) => e.url == newTask.url)
        .length;
  }
}