DieselとはRust製のORMです。
Dieselを使ってTransaction内で外部のAPIを叩きたい。
その際に、特定のレコードは行ロックしておきたい。
その戻り値を使ってレコードを更新したい。
今回はその方法を書き溜め。
DieselのTransaction内はsyncのためawaitは使用できない。
reqwestを使うとした場合、blocking::Clientを使用する必要がある。
しかし、ActixWebを利用している場合では、そのままblockingを実行しようとするとコンパイルエラーになる。
async関数の中でtransactionを呼び出すことになるため、
色々試してみてたところRuntime Handleからspawn_blockingすることで対応可能だった。
handle.spawn_blocking(move || のところがポイントだと理解した。
tokioはversion 0.2, reqwestは0.1, dieselは1.4.4です。
| 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 | async fn hoge(key_params: String) -> {         let handle = tokio::runtime::Handle::current();         handle.spawn_blocking(move || {             conn.transaction::<_, MyError, _>(|| {                 let mut user: User = users                     .filter(user_key.eq(key_params))                     .for_update()                     .load::<User>(&conn)?.pop().unwrap(),             });             let client = reqwest::blocking::Client::new();             let map: Param = Param {                 user_key: key_params             }             let body = client.post("https://example.com/get_uniq_key")                 .json(&map)                 .send()?;             let j: Response = body.json()?;             let mut update_user_params = UserUpdate {                 id: user.id,                 uniq_key: Response.uniq_key             };             let updated_user = diesel::update(&user)                 .set(update_user_params)                 .load::<User>(&conn);             Ok(());         }).await?; } | 
Rust勉強しなきゃ...
じゃあね〜〜〜〜。
