포트폴리오 - 데이터베이스 커넥션 풀

갤럭시4414·2022년 11월 8일
0

지난번에 커넥션 풀이 필요할 것 같아서 간단히 또 찾아 보았다.
쉽게 나오는 건 R2D2, BB8 이렇게 두가지 였는데, 왜 C3PO 가 없지, 그래도 최신형 모델인 BB8 이 좋아 보여서 BB8 으로 트라이 해보자. (사실 R2D2 는 구형이라서 그런지 tokio-postgres 를 지원 안하는 것 같아서...)

예제가 좀 부실하지만 일단 복붙하자.

역시나 디펜던시 추가부터..

backend/Cargo.toml

...

[dependencies]
tokio = "1.0"
rocket = "0.5.0-rc.2"
bb8 = "0.8"
bb8-postgres = "0.8.1"
tokio-postgres = "0.7.7"

코드도 간단히 고쳐보자.

backend/main.rs


use bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use tokio_postgres::{NoTls};

async fn test_db() -> Result<(), tokio_postgres::Error> {
    let pg_mgr = PostgresConnectionManager::new_from_stringlike(
        "host=localhost user=postgres password=hello1234$#@! dbname=portfolio_test",
        tokio_postgres::NoTls,
    ).unwrap();

    let pool = Pool::builder().build(pg_mgr).await.unwrap();

    let mut connection = pool.get().await.unwrap();
    let ret = connection.query("SELECT id, name FROM tb_user", &[]).await.unwrap();

    for row in ret {

pool 로 connection 을 생성하고 쿼리를 날렸다.
AsyncTask job을 만드는 부분이 없어서 깔끔해졌다.

그런데 현재는 test_db 를 호출할 때 마다 커넥션 풀을 만들기 때문에 요거를 옮겨야 할 것 같다. rocket에 요 녀석을 저장할 수 있는 곳이 있나 찾아보자.

찾아보니 rocket 에서는 이런 데이터를 state 란 곳에 저장하는 것 같다.

일단 state 에 저장하는 건 쉽다. 다음처럼 manage 에 추가만 해주면 된다.

backend/main.rs

#[launch]
async fn rocket() -> _ {
    let pg_mgr = PostgresConnectionManager::new_from_stringlike(
        "host=localhost user=postgres password=hello1234$#@! dbname=portfolio_test",
        tokio_postgres::NoTls,
    ).unwrap();

    let pool = Pool::builder().build(pg_mgr).await.unwrap();

    rocket::build()
        .manage(pool)
        .mount("/", routes![index])
}

backend/main.rs

#[get("/")]
async fn index(dbPool: &State<DBPool> ) -> &'static str {

어려운 건 (!?) 쓰는 쪽... state의 type 을 명확히 알아야 쓸수가 있다 =_=;; 정녕 이렇게 하는 것인가...

일단 삽질로 pool 이 Pool<...> 이란걸 알아서 다음과 같이 type 문으로 alias 를 지정했다

backend/main.rs

type DBPool = Pool<bb8_postgres::PostgresConnectionManager<tokio_postgres::tls::NoTls>>;

backend/main.rs

#[get("/")]
async fn index(dbPool: &State<DBPool> ) -> &'static str {
    test_db(dbPool).await;
    return "Hello, world!"
}

async fn test_db(dbPool: &DBPool) -> Result<(), tokio_postgres::Error> {
    let mut connection = dbPool.get().await.unwrap();
    let ret = connection.query("SELECT id, name FROM tb_user", &[]).await.unwrap();

...

알흠다운 세상...

그러나 저 위에 위에 Type 을 지정하는 부분이 매우 많이 맘에 들지 않는다.
뭔가 엘레강스한 방법이 있을 것 같은데... 내일 찾아봐야겠다.

profile
풀스택개발자를꿈꾸는

0개의 댓글