Bonjour,
J'essaie de faire un pool de connexion SQL en Rust, pour parallèliser mes requêtes.
Voici le code que j'ai fait, extrait d'un projet de web application que je fais avec Rocket (https://rocket.rs/) .
Et les dépendances de mon Cargo.toml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #![allow(unused_imports)] use sqlx::Row; use rocket::tokio::time::{ self, Duration }; fn main() { let bdd_connexion = rocket::tokio::runtime::Runtime::new().unwrap().block_on(sqlx::PgPool::connect("postgresql://postgres@localhost:5433/postgres")); match bdd_connexion { Ok(bdd_connexion) => { let mut date = chrono::Local::now(); println!( "{} Debut, nombre de connexion : {}", date.format( "%H:%M:%S" ), bdd_connexion.size() ); rocket::tokio::runtime::Runtime::new().unwrap().block_on(list_fonction_asynchone(bdd_connexion) ); date = chrono::Local::now(); println!( "{} Fin.", date.format( "%H:%M:%S" ) ); } Err(erreur) => { panic!( "Impossible de se connecter à la base de données : {}", erreur ); } } } async fn list_fonction_asynchone(pool: sqlx::Pool<sqlx::Postgres>) { let mut date = chrono::Local::now(); println!( "{} Debut des appels.", date.format( "%H:%M:%S" ) ); let tache1 = fonction_asynchone(pool.clone()); let tache2 = fonction_asynchone(pool.clone()); date = chrono::Local::now(); println!( "{} Fin des appels, attente fin...", date.format( "%H:%M:%S" ) ); rocket::tokio::join!(tache1, tache2); } async fn fonction_asynchone(pool: sqlx::Pool<sqlx::Postgres>) { let mut date = chrono::Local::now(); println!( "{} Debut de la fonction asynchrone", date.format( "%H:%M:%S" ) ); // time::sleep(Duration::from_secs(5)).await; // Simuler un délai let _rows = sqlx::query("SELECT pg_sleep(5) || 'toto' as resultat").map(|row: sqlx::postgres::PgRow| { let resultat: String = row.get("resultat"); resultat }).fetch_all(&pool).await; date = chrono::Local::now(); println!( "{} Fin de la fonction asynchrone", date.format( "%H:%M:%S" ) ); }
Quand le commente les lignes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 [dependencies] rocket = { version = "*", features = [ "json" ] } sqlx = { version = "*", features = [ "runtime-tokio-native-tls", "sqlite", "postgres" ] } r2d2 = { version = "*" } chrono = { version = "*" }
Et que je décommente la ligne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 let _rows = sqlx::query("SELECT pg_sleep(5) || 'toto' as resultat").map(|row: sqlx::postgres::PgRow| { let resultat: String = row.get("resultat"); resultat }).fetch_all(&pool).await;
J'obtiens bien une execution parallèlisé :
Code : Sélectionner tout - Visualiser dans une fenêtre à part time::sleep(Duration::from_secs(5)).await;
Les 2 fonctions qui attendent 5 secondes se font ensemble.13:10:00 Debut, nombre de connexion : 1
13:10:00 Debut des appels.
13:10:00 Fin des appels, attente fin...
13:10:00 Debut de la fonction asynchrone
13:10:00 Debut de la fonction asynchrone
13:10:05 Fin de la fonction asynchrone
13:10:05 Fin de la fonction asynchrone
13:10:05 Fin.
Par contre avec la connexion SQL j'ai :
La première fonction attends bien 5 secondes, mais la seconde se termine au bout de 30 secondes...13:07:00 Debut, nombre de connexion : 1
13:07:00 Debut des appels.
13:07:00 Fin des appels, attente fin...
13:07:00 Debut de la fonction asynchrone
13:07:00 Debut de la fonction asynchrone
13:07:05 Fin de la fonction asynchrone
13:07:30 Fin de la fonction asynchrone
13:07:30 Fin.
Comment bien coder un pool de connexion SQL en Rust ?
Merci par avance !
Partager