openlang

await for по ReceivePort никогда не завершается после того, как изоляты закончили

всем привет, у меня небольшая тулза на Dart, она делает сводку по CSV с температурами, и я запускаю по одному изоляту на файл, чтобы большие не ждали друг друга. запускаю в WSL так:

dart run bin/summarize.dart data/north.csv data/south.csv -v

с -v вижу две строки "spawned worker", потом две строки "got ... rows", и количество строк правильное. то есть воркеры явно работают. но потом ничего. ни таблицы, ни возврата в консоль, приходится жать Ctrl+C.

сначала я думал, что readAsLinesSync в воркере что-то блокирует, потом обернул тело воркера в try/catch, но ничего не бросается и ничего не меняется.

что меня смущает: я помню, что цикл в main сам заканчивался, когда все запущенные изоляты завершались. поэтому я и использую await for, а не считаю результаты. вот основная часть:

final port = ReceivePort();

for (final p in paths) {
  await Isolate.spawn(summarizeFile, WorkOrder(p, port.sendPort));
  log.debug('spawned worker for $p');
}

final results = <FileSummary>[];
await for (final msg in port) {
  final s = msg as FileSummary;
  results.add(s);
  log.info('got ${s.path}: ${s.count} rows');
}

results.sort((a, b) => a.path.compareTo(b.path));
printTable(results);

воркер в конце просто делает order.replyTo.send(FileSummary(...)) и возвращается. Dart 3.x, свежий. что-то поменялось в том, когда этот цикл заканчивается? не хочу переписывать сбор результатов, пока не пойму, в чём дело.

Переведено с английскогоПоказать оригинал

Разговор продолжается 2

Следуя доводам
  1. Ссылка на ответ

    Ничего не менялось — ReceivePort сам никогда не закрывается. await for завершается только когда порт закрыт, а его никто не закрывает. То, что изоляты завершились, не считается. Скорее всего, вы помните это по схеме с Isolate.run или с трюком с exit-портом.

    Самое простое решение: считайте результаты и вызовите port.close(), когда наберётся paths.length. Или используйте Isolate.run на каждый файл и Future.wait.

    Документация: https://api.dart.dev/stable/dart-isolate/ReceivePort-class.html

    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. Контекст отменён, но горутины-воркеры живы после первой ошибки (всегда workers + 2)

    Всем привет, Пишу небольшой CLI на Go, shotcheck, который проверяет каждый PNG в папке на точное соответствие размеру, которы…

    Ответы 4Последняя активность go
  2. Пометка фильтра как async не помогла с фризом

    ledgerscan, поиск по 400k записей. сделал run async и вызываю через await из main, думал, что 100 мс heartbeat Timer продолжи…

    Ответы 2Последняя активность dart
  3. В outliers.log строк больше, чем в счётчике :outliers, 8 futures

    Я сворачиваю 20000 симулированных показаний приливов в один atom из 8 futures. Каждое показание выше порога ещё и дописываетс…

    Ответы 1Последняя активность clojure