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/) .

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" ) );
}
Et les dépendances de mon Cargo.toml :

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 = "*" }
Quand le commente les lignes :

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;
Et que je décommente la ligne :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
time::sleep(Duration::from_secs(5)).await;
J'obtiens bien une execution parallèlisé :

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.
Les 2 fonctions qui attendent 5 secondes se font ensemble.

Par contre avec la connexion SQL j'ai :

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.
La première fonction attends bien 5 secondes, mais la seconde se termine au bout de 30 secondes...

Comment bien coder un pool de connexion SQL en Rust ?

Merci par avance !