diff --git a/FRENCH/examples-sources/09_02_async_tcp_server/Cargo.toml b/FRENCH/examples-sources/09_02_async_tcp_server/Cargo.toml new file mode 100644 index 00000000..196d1a58 --- /dev/null +++ b/FRENCH/examples-sources/09_02_async_tcp_server/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "async_tcp_server" +version = "0.1.0" +authors = ["Your Name +} +// ANCHOR_END: handle_connection_async diff --git a/FRENCH/examples-sources/09_03_slow_request/Cargo.toml b/FRENCH/examples-sources/09_03_slow_request/Cargo.toml new file mode 100644 index 00000000..aff14020 --- /dev/null +++ b/FRENCH/examples-sources/09_03_slow_request/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "slow_request" +version = "0.1.0" +authors = ["Your Name +} +// ANCHOR_END: handle_connection_async diff --git a/FRENCH/examples/09_03_slow_request/Cargo.toml b/FRENCH/examples/09_03_slow_request/Cargo.toml new file mode 100644 index 00000000..aff14020 --- /dev/null +++ b/FRENCH/examples/09_03_slow_request/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "slow_request" +version = "0.1.0" +authors = ["Your Name + +# Exécuter du code asynchrone + +Un serveur HTTP doit être capable de servir plusieurs clients en concurrence, +et par conséquent, il ne doit pas attendre que les requêtes précédentes soient +terminées pour s'occuper de la requête en cours. +Le livre Rust [résout ce +problème](https://jimskapt.github.io/rust-book-fr/ch20-02-multithreaded.html#transformer-notre-serveur-monot%C3%A2che-en-serveur-multit%C3%A2ches) +en créant un groupe de tâches où chaque connexion est gérée sur son propre +processus. Nous allons obtenir le même effet en utilisant du code asynchrone, +au lieu d'améliorer le débit en ajoutant des processus. + + + +Modifions le `gestion_connexion` pour retourner une future en la déclarant +comme étant une fonction asynchrone : + +```rust,ignore +{{#include ../../examples/09_02_async_tcp_server/src/main.rs:handle_connection_async}} +``` + + + +L'ajout de `async` à la déclaration de la fonction change son type de retour de +`()` à un type qui implémente `Future`. + + + +Si nous essayons de compiler cela, le compilateur va nous avertir que cela ne +fonctionnera pas : + +```console +$ cargo check + Checking async-rust v0.1.0 (file:///projects/async-rust) +warning: unused implementer of `std::future::Future` that must be used + -- > src/main.rs:12:9 + | +12 | gestion_connexion(flux); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: futures do nothing unless you `.await` or poll them +``` + + + +Comme nous n'avons pas utilisé `await` ou `poll` sur le résultat de +`gestion_connexion`, cela ne va jamais s'exécuter. Si vous lancez le serveur et +visitez `127.0.0.1:7878` dans un navigateur web, vous constaterez que la +connexion est refusée, notre serveur ne prend pas en charge les requêtes. + + + +Nous ne pouvons pas utiliser `await` ou `poll` sur des futures dans du code +synchrone tout seul. +Nous allons avoir besoin d'un environnement d'exécution asynchrone pour gérer +la planification et l'exécution des futures jusqu'à ce qu'elles se terminent. +Vous pouvez consulter la [section pour choisir un environnement +d'exécution](../08_ecosystem/00_chapter.md) pour plus d'information sur les +environnements d'exécution, exécuteurs et réacteurs asynchrones. +Tous les environnements d'exécution listés vont fonctionner pour ce projet, +mais pour ces exemples, nous avons choisi d'utiliser la crate `async-std`. + + + +## Ajouter un environnement d'exécution asynchrone + +L'exemple suivant va monter le remaniement du code synchrone pour utiliser un +environnement d'exécution asynchrone, dans ce cas `async-std`. +L'attribut `#[async_std::main]` de `async-std` nous permet d'écrire une +fonction `main` asynchrone. +Pour l'utiliser, il faut activer la fonctionnalité `attributes` de `async-std` +dans `Cargo.toml` : + +```toml +[dependencies.async-std] +version = "1.6" +features = ["attributes"] +``` + + + +Pour commencer, nous allons changer pour une fonction `main` asynchrone, et +utiliser `await` sur la future retournée par la version asynchrone de +`gestion_connexion`. Ensuite, nous testerons comment le serveur répond. Voici à +quoi cela ressemblerait : + +```rust +{{#include ../../examples/09_02_async_tcp_server/src/main.rs:main_func}} +``` + +Maintenant, testons pour voir si notre serveur peut gérer les connexions en +concurrence. Transformer simplement `gestion_connexion` en asynchrone ne +signifie pas que le serveur puisse gérer plusieurs connexions en même temps, et +nous allons bientôt voir pourquoi. + + + +Pour illustrer cela, simulons une réponse lente. +Lorsqu'un client fait une requête vers `127.0.0.1:7878/pause`, notre serveur va +attendre 5 secondes : + + + +```rust,ignore +{{#include ../../examples/09_03_slow_request/src/main.rs:handle_connection}} +``` + +C'est très ressemblant à la [simulation d'une requête +lente](https://jimskapt.github.io/rust-book-fr/ch20-02-multithreaded.html#simuler-une-longue-requ%C3%AAte-%C3%A0-traiter-avec-limpl%C3%A9mentation-actuelle-du-serveur) +dans le livre Rust, mais avec une différence importante : +nous utilisons la fonction non bloquante `async_std::task::sleep` au lieu de la +fonction bloquante `std::thread::sleep`. +Il est important de se rappeler que même si un code est exécuté dans une +fonction asynchrone et qu'on utilise `await` sur elle, elle peut toujours +bloquer. +Pour tester si notre serveur puisse gérer les connexions en concurrence, nous +avons besoin de nous assurer que `gestion_connexion` n'est pas bloquante. + + + +Si vous exécutez le serveur, vous constaterez qu'une requête vers +`127.0.0.1:7878/pause` devrait bloquer toutes les autres requêtes entrantes +pendant 5 secondes ! +C'est parce qu'il n'y a pas d'autres tâches concurrentes qui peuvent progresser +pendant que nous utilisons `await` sur le résultat de `gestion_connexion`. +Dans la prochaine section, nous allons voir comment utiliser du code asynchrone +pour gérer en concurrence les connexions. diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index beeca743..1b38e2b0 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1,3 +1,5 @@ # Table des matières + - [Exécuter du code asynchrone](09_example/01_running_async_code.md) + [Traduction des termes](translation-terms.md) diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 0917f018..4c179b20 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -5,3 +5,5 @@ français. | Anglais | Français | Remarques | | ------- | ------ | ------ | +| refactoring | remaniement | - | +| snip | partie masquée ici | dans un encart |