В случае с методом #process_multiple
нам нужно будет немного улучшить наш код параллелизма, чтобы лучше поддерживать обработку исключений. Хорошей практикой считается обработка любых исключений, возникающих в волокне, внутри самого волокна.
К сожалению, на данный момент работа с каналами и волокнами находится на несколько более низком уровне, чем хотелось бы в идеале. Есть несколько выдающихся предложений, например https://github. com/crystal-lang/crystal/issues/6468, но в стандартной библиотеке еще не реализовано ничего, что позволяло бы использовать некоторые встроенные абстракции или API более высокого уровня. С другой стороны, проблема, которую мы хотим решить, довольно тривиальна.
В последней главе мы добавили отправку с использованием блока ensure
для корректной обработки контекстов сбоя, но упомянули, что эта реализация не идеальна, главным образом потому, что мы хотим иметь возможность различать контексты успеха и неудачи. Чтобы решить эту проблему, мы можем изменить канал, чтобы он принимал объединение Bool | Exception
вместо просто Bool
. Затем, снова используя короткую форму rescue
, мы можем отправить каналу возникшее исключение, заменив блок ensure
. В конечном итоге это будет выглядеть так:
channel.send true
rescue ex : Exception
channel.send ex
Подобно другим блокам восстановления, этот также будет идти сразу после channel.send true
, но перед конечным тегом блока spawn
. Затем нам нужно обновить логику получения для обработки значения исключения, поскольку в данный момент мы всегда игнорируем полученное значение. Для этого мы обновим цикл, чтобы проверить тип полученного значения, и поднимем его, если это тип Exception
:
input_args.size.times do
case v = channel.receive
in Exception then raise v
in Bool
# Skip
end
end
Теперь, когда мы вызываем исключение из волокна внутри самого метода, наш блок восстановления в методе теперь будет вызываться правильно. Полный метод #process_ multiple
находится в папке главы на GitHub: https://github.com/PacktPublishing/Crystal-Programming/blob/main/ Chapter07/process_multiple.cr.
Я обнаружил, что самый простой способ протестировать нашу логику отправки уведомлений — это передать файл, который не существует в режиме нескольких файлов. Например, запустив ./bin/transform -m .random-file.txt
должен привести к отображению уведомления, информирующего вас о том, что при попытке открыть этот файл произошла ошибка.
Резюме
Увы, мы подошли к завершению нашего проекта CLI. За последние четыре главы мы значительно улучшили приложение. В процессе работы мы также расширили наши знания о различных концепциях Crystal. Хотя это и конец этой части книги, это не обязательно должен быть конец CLI. Не стесняйтесь продолжать самостоятельно, добавляя функции по своему желанию. В конечном счете, это поможет закрепить концепции, представленные на этом пути.
В следующей части книги будут представлены некоторые новые проекты, ориентированные на веб-разработку, и будет использовано все, что вы узнали до сих пор. Он также потратит некоторое время на демонстрацию различных шаблонов проектирования, которые могут пригодиться в ваших будущих проектах. И так, чего же ты ждешь? Прежде всего нужно научиться использовать внешние проекты Crystal, также известные как шарды, в качестве зависимостей внутри вашего собственного проекта. Иди, начни!
Часть 3. Обучение на практике — веб-приложение
Эта часть продолжит парадигму «Обучение на практике» с другим распространенным типом приложений: веб-фреймворком. Эта часть будет опираться на информацию из первых двух частей. Чаще всего веб-приложение создается с помощью фреймворка. К счастью, в экосистеме Crystal есть из чего выбирать. Хотя лучшая платформа для использования варьируется от варианта использования к варианту использования, мы собираемся сосредоточиться на Athena Framework.
Эта часть содержит следующие главы:
8. Использование внешних библиотек