У меня есть простое приложение с эффектом кошки, которое скачивает сайт с URL, указанного в качестве аргумента.Во время загрузки приложение должно отображать «полосу загрузки», записывая точки (.
) в консоль.Я реализовал это, выполнив гонку из двух операций ввода-вывода одного для загрузки другого для отображения точек.
Это целое приложение на scastie .
Самая важная часть здесь:
def loader(): IO[Unit] = for {
_ <- console.putStr(".")
_ <- timer.sleep(Duration(50, MILLISECONDS)) *> loader()
} yield {}
def download(url: String): IO[String] = IO.delay(Source.fromURL(url)).map(_.mkString)
def run(args: List[String]): IO[Unit] = {
args.headOption match {
case Some(url) =>
for {
content <- IO.race(download(url), loader()).map(_.left.get)
_ <- console.putStrLn() *> console.putStrLn(s"Downloaded site from $url. Size of downloaded content is ${content.length}.")
} yield {}
case None => console.putStrLn("Pass url as argument.")
}
}
Все работает, как я ожидал, когда я запускаю его, я получаю:
.............. Скачанный сайт с https://www.scala -lang.org .Размер загружаемого контента 47738.
Единственная проблема в том, что приложение никогда не закрывается.
Насколько я проверял загрузчик IO корректно отменяется.Я даже могу добавить что-то вроде этого:
urlLoader.run(args) *> console.putStrLn("???") *> IO(ExitCode.Success)
И отображается ???
.
Также, когда я удаляю race , приложение корректно завершает работу.
Итак, мой вопрос, как я могу это исправить и завершить работу моего приложения?