Skip to content

Russian translation #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions translations/ru/01_getting_started/01_chapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Начало работы

Добро пожаловать в книгу "Асинхронное программирование в Rust"! Если вы
собираетесь начать писать асинхронный код на Rust, вы находитесь в правильном
месте. Строите ли вы веб-сервер, базу данных или операционную систему, эта книга
покажет вам как использовать инструменты асинхронного программирования, чтобы
получить максимальную отдачу от вашего оборудования.

## Что охватывает эта книга?

Эта книга призвана стать исчерпывающим, современным
руководством по использованию асинхронных языковых
возможностей и библиотек Rust, подходящим как новичкам, так и
опытным разработчикам.

- Ранние главы содержат введение в асинхронное программирование в целом, а также
его особенности в Rust.

- В средних главах обсуждаются ключевые утилиты и инструменты
управления потоком, которые вы можете использовать, когда
пишете асинхронный код. Также здесь описаны лучшие практики
структурирования библиотек и приложений для получения
максимальной производительности и повторного использования кода.

- Последняя глава книги покрывает асинхронную экосистему и
предоставляет ряд примеров того, как можно выполнить общие
задачи.

Итак, давайте исследуем захватывающий мир асинхронного
программирования в Rust!
49 changes: 49 additions & 0 deletions translations/ru/01_getting_started/02_why_async.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Для чего нужна асинхронность?

Все мы любим то, что Rust позволяет нам писать быстрые и безопасные
приложения. Но для чего писать асинхронный код?

Асинхронный код позволяет нам запускать несколько задач
параллельно в одном потоке ОС. Если вы в обычном приложении
хотите одновременно загрузить две разных web-страницы, вы
должны разделить работу между двумя разным потоками, как тут:

```rust
{{#include ../../../examples/01_02_why_async/src/lib.rs:get_two_sites}}
```

Для многих приложений это замечательно работает - в конце концов,
потоки были разработаны именно для этого: одновременно
запускать несколько разных задач. Однако, они имеют некоторые
ограничения. В процессе переключения между разными потоками и
обменом данными между ними возникает много накладных расходов.
Даже поток, который сидит и ничего не делает, использует ценные
системные ресурсы. Асинхронный код предназначен для устранения
этих проблем. Мы можем переписать функции выше используя
нотацию `async`/`.await`, которая позволяет
нам запустить несколько задач одновременно, не создавая нескольких потоков:

```rust
{{#include ../../../examples/01_02_why_async/src/lib.rs:get_two_sites_async}}
```

В целом, асинхронные приложения могут быть намного быстрее и
использовать меньше ресурсов, чем соответствующая
многопоточная реализация. Однако, есть и обратная сторона.
Потоки изначально поддерживаются операционной системой и их
использование не требует какой-либо специальной модели
программирования - любая функция может создать поток и вызов
функции, использующей потоки, обычно так же прост, как вызов
обычной функции. Тем не менее, асинхронные функции требуют
специальной поддержки со стороны языка или библиотек. В Rust,
`async fn` создаёт асинхронную функцию, которая
возвращает `Future`. Для выполнения тела функции,
возвращённая `Future` должна быть завершена.

Важно помнить, что традиционные приложения с потоками могут
быть вполне эффективными и предсказуемость Rust и небольшой
объём используемой памяти могут значить, что вы можете далеко
продвинуться и без использования `async`.
Повышенная сложность асинхронной модели программирования
не всегда стоит этого и важно понимать, когда ваше приложение
будет лучше работать с использованием простой поточной модели.
24 changes: 24 additions & 0 deletions translations/ru/01_getting_started/03_state_of_async_rust.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Состояние асинхронности в Rust

Асинхронная экосистема Rust претерпела большие изменения с течением времени,
поэтому может быть трудно понять, какие инструменты использовать, в какие библиотеки инвестировать,
или какую документацию читать. Однако типаж `Future` внутри стандартной библиотеки и `async`/`await` в языке были недавно стабилизированы.
Таким образом, экосистема в целом находится в процессе миграции
к недавно стабилизированному API, после чего точка оттока будет значительно
уменьшена.

Тем не менее, сейчас экосистема всё ещё находится в стадии
активной разработки и асинхронный опыт в Rust не отполирован.
Многие библиотеки до сих пор используют пакет
`futures` версии 0.1, а это значит, что для
взаимодействия с ними разработчикам часто требуется
функциональность `compat` из пакета
`futures` версии 0.3. Синтаксис `async`/`await` до сих пор достаточно нов. Важные расширения
синтаксиса, такие как `async fn` для методов типажей, до
сих пор не реализованы, и текущие сообщения компилятора об
ошибках могут быть сложны для восприятия.

Это говорит о том, что Rust на пути к более эффективной и
эргономичной поддержке асинхронного программирования и если
вы не боитесь изменений, наслаждайтесь погружением в мир
асинхронного программирования в Rust!
67 changes: 67 additions & 0 deletions translations/ru/01_getting_started/04_async_await_primer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Пример `async`/`.await`

`async`/`.await` - это встроенные в Rust
инструменты для написания асинхронного кода, который выглядит
как синхронный код. Ключевое слово `async` преобразует блок кода в конечный
автомат, который реализует типаж, называемый `Future`. В то время как вызов
блокирующей функции в синхронном методе заблокирует весь поток, заблокированная
`Future` вернёт контроль над потоком, позволяя работать другим `Future`.

Для создания асинхронной функции, вы можете использовать
синтаксис `async fn`:

```rust
async fn do_something() { ... }
```

Значение, возвращённое`async fn` является `Future`. Что бы ни произошло,
`Future` должна быть запущена в исполнителе.

```rust
{{#include ../../../examples/01_04_async_await_primer/src/lib.rs:hello_world}}
```

Внутри `async fn` можно использовать
`.await` для ожидания завершения другого типа,
реализующего типаж `Future` (например, полученного из другой `async fn`).
В отличие от `block_on`, `.await` не блокирует текущий поток, но асинхронно ждёт
завершения футуры, позволяя другим задачам выполняться, если в данный момент
футура не может добиться прогресса.

Например, представим что у нас есть три синхронный функции `async fn`:
`learn_song`, `sing_song` и `dance`:

```rust
async fn learn_song() -> Song { ... }
async fn sing_song(song: Song) { ... }
async fn dance() { ... }
```

Одним из способов выполнения функций учить, петь и танцевать будет остановка на
каждом из них:

```rust
{{#include ../../../examples/01_04_async_await_primer/src/lib.rs:block_on_each}}
```

Тем не менее, в этом случае мы не получаем наилучшей
производительности - в один момент мы делаем только одно дело!
Очевидно, что мы должны выучить песню до того, как петь её, но
мы можем танцевать в то же время, пока учим песню и поём её.
Чтобы сделать это, мы создадим две отдельные `async fn`, которые могут
запуститься параллельно:

```rust
{{#include ../../../examples/01_04_async_await_primer/src/lib.rs:block_on_main}}
```

В этом примере, изучение песни должно быть завершено до пения, но и изучение и
пение могут завершиться одновременно с танцем. Если мы использовали бы
`block_on(learn_song())` вместо `learn_song().await` внутри `learn_and_sing`,
поток не смог бы делать ничего другого, пока работает `learn_song`. Из-за этого
мы одновременно с этим не можем танцевать.
С помощью ожидания `.await` футуры `learn_song`, мы разрешаем другим задачам
захватить текущий поток, пока `learn_song` заблокирована. Это делает возможным
запуск нескольких футур, завершающихся параллельно в одном потоке.

Теперь мы изучили основы `async`/`.await`, давайте посмотрим их в действии.
88 changes: 88 additions & 0 deletions translations/ru/01_getting_started/05_http_server_example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Применение: HTTP сервер

Давайте используем `async`/`.await` для создания echo-сервера!

Для начала, запустите `rustup update stable` чтобы
быть уверенным, что используете стабильную версию Rust - 1.39 или более новую.
Когда вы закончите это, создайте новый проект с
помощь `cargo new async-await-echo` и
откройте созданную директорию `async-await-echo`.

Добавим некоторые зависимости в файл `Cargo.toml`:

```toml
{{#include ../../../examples/01_05_http_server/Cargo.toml:9:18}}
```

Теперь, когда у нас есть свои зависимости, давайте начнём писать код. Вот список
зависимостей, которые необходимо добавить:

```rust
{{#include ../../../examples/01_05_http_server/src/lib.rs:imports}}
```

Как только закончим с импортами, мы можем собрать вместе весь
шаблонный код, который позволит обрабатывать запросы:

```rust
{{#include ../../../examples/01_05_http_server/src/lib.rs:boilerplate}}
```

Если вы сейчас запустите `cargo run`, в консоли вы
увидите сообщение "Listening on http://127.0.0.1:3000". Если вы
откроете URL в вашем любимом браузере, вы увидите как в нём
отобразится "hello, world!". Поздравляем! Вы только что написали
свой первый асинхронный web-сервер на Rust.

Вы также можете посмотреть сам запрос, который содержит такую
информацию, как URI, версию HTTP, заголовки и другие
метаданные. Например, мы можем вывести URI запроса
следующим образом:

```rust
println!("Got request at {:?}", req.uri());
```

Вы могли заметить, что мы до сих пор не делали ничего
асинхронного для обработки запроса - мы только незамедлительно
ответили на него, мы не пользуемся гибкостью, которую нам даёт
`async fn`. Вместо этого, мы только возвращаем
статическое сообщение. Давайте попробуем проксировать
пользовательский запрос на другой web-сайт используя
HTTP-клиент Hyper'а.

Мы начнём с парсинга URL, который мы хотим запросить:

```rust
{{#include ../../../examples/01_05_http_server/src/lib.rs:parse_url}}
```

Затем мы создадим новый `hyper::Client` и
используем его для создания `GET` запроса, который
вернём пользователю ответ:

```rust
{{#include ../../../examples/01_05_http_server/src/lib.rs:get_request}}
```

`Client::get` возвращает
`hyper::client::FutureResponse`, который реализует
`Future<Output = Result<Response, Error>>`
(или `Future<Item = Response, Error = Error>` в
терминах `futures` 0.1). Когда мы разрешаем (`.await`)
футуру, отправляется HTTP-запрос, текущая задача
приостанавливается и становится в очередь, чтобы продолжить
работу после получения ответа.

Если вы сейчас запустите `cargo run` и откроете
`http://127.0.0.1:3000/foo` в браузере, вы увидите
домашнюю страницу Rust, а в консоли следующий вывод:

```
Listening on http://127.0.0.1:3000
Got request at /foo
making request to http://www.rust-lang.org/en-US/
request finished-- returning response
```

Поздравляем! Вы только что проксировали HTTP запрос.
14 changes: 14 additions & 0 deletions translations/ru/02_execution/01_chapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Под капотом: выполнение `Future` и задач

В этом разделе мы рассмотрим как планируются `Future`
и асинхронные задачи. Если вам только интересно изучить как писать
высокоуровневый код, который использует существующие типы
`Future`, и не интересуетесь тем, как работает `Future`, то можете сразу перейти к главе
`async`/`await`. Тем не менее, некоторые
темы, которые обсуждаются в этой главе, полезны для понимания
работы `async`/`await` кода и построения
новых асинхронных примитивов. Если сейчас вы решили пропустить
этот раздел, вы можете добавить его в закладки, чтобы вернуться к
нему в будущем.

Теперь давайте рассмотрим типаж `Future`.
Loading