포트폴리오 - 데이터베이스 연결 2

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

지난번에 synchronous 버전으로 삽질하다가 실패해서 asynchronous 버전인 tokio-postgres 로 다시 도전 했다.

우선 crate를 바꾸자.

backend/Cargo.toml

...

[dependencies]
rocket = "0.5.0-rc.2"
tokio-postgres = "0.7.7"

main.rs에 샘플을 복붙하자.

backend/main.rs

#[macro_use] extern crate rocket;
extern crate tokio_postgres;


use tokio_postgres::{NoTls};

async fn test_db() -> Result<(), tokio_postgres::Error> {
    let (client, connection) = tokio_postgres::connect("host=localhost user=postgres password=hello1234$#@! dbname=portfolio_test", NoTls).await?;

    let ret =  client.query("SELECT id, name FROM tb_user;", &[]).await?;

    for row in ret {
        let id: i32 = row.get(0);
        let name: &str = row.get(1);
    
        println!("found user: {} {}", id, name);
    }

    return Ok(())
}

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

전반적으로 샘플에 있는 tokio_postgres 로 변경하고, await 를 붙여서 비동기로 결과를 받게 했다.

거기에 샘플 코드를 보다 보니 리턴 타입으로 Result<(), tokio_postgres::Error> 으로 써서 좀 더 깔끔하게 ? 로 처리가 가능했다. (이전에는 .ok()? 로 처리)
ok 를 붙이는 건 rust 컴파일러가 알려주었는데 이걸 알려줬어야지.

cargo run 을 다시 해 보자.
그런데 빌드는 잘 된것 같은데, 해당 url 을 열면 응답이 오지 않는다.

=_=

체크를 하다보니 요 라인에서 응답이 오지 않는다.

    let ret =  client.query("SELECT id, name FROM tb_user;", &[]).await?;

샘플 코드를 보다 보니 빼먹은게 있었다. 뭔가 자동으로 생성 될 줄 알았는데, 명시적으로 async task 를 만들어 줘야 하나보다.

tokio 를 추가하고 async task 를 스폰해서 커넥션을 맺어주자.

backend/Cargo.toml

...

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

backend/main.rs

#[macro_use] extern crate rocket;
extern crate tokio_postgres;
extern crate tokio;

use tokio_postgres::{NoTls};

async fn test_db() -> Result<(), tokio_postgres::Error> {
    let (client, connection) = tokio_postgres::connect("host=localhost user=postgres password=hello1234$#@! dbname=portfolio_test", NoTls).await?;

    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });

실행 해 보니 잘 된다.

🚀 Rocket has launched from http://127.0.0.1:8000
GET / text/html:
   >> Matched: (index) GET /
found user: 1 galaxy
   >> Outcome: Success
   >> Response succeeded.

간단하게 샘플을 복붙해서 만들었는데 살펴볼께 많이 생겼다.

  • tokio::spawn 할 때 async move 라는 녀석을 쓴다. 메모리 관련된 move 를 봐야지 했었는데, clojure 용을 먼저 보게 생겼다. 왠지 capture 랑 연관이 있을 것 같은...
  • postgresql 관련 커넥션 풀을 찾아봐야 할 것 같다. + async task 생성이 필요한데 이것도 같이 처리 할 수 있어야 겠다.
  • test_db().await 처럼 비동기 함수를 호출 할 때 await 로 기다리는데, await 없이 실행하는 방법도 찾아보자.
profile
풀스택개발자를꿈꾸는

0개의 댓글