cockroachdb / cockroachdb/example-app-rust-postgres

Question - Tokio Postgres (Async)

Open
#6 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
6
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Hello, i have been trying to replicate the example but using Tokio-Postgres. I would like to know if my implementation is correct.

I'm using **deadpool_postgres** too.

```rust
#[derive(Clone)]
pub struct TransactionRepository {
pool: Pool,
}

impl TransactionRepository {
pub fn new(pool: Pool) -> Self {
TransactionRepository { pool }
}
}

#[async_trait]
impl TransactionRepositoryInterface for &TransactionRepository {
async fn make_transaction(&self, data: &WalletTransferEntity) -> Result<(), AppError> {
let mut client: Client = self.pool.get().await.map_err(|e| AppError::DatasourceError(e.to_string()))?;
let mut txn = client.transaction().await?;
let mut i = 0;
match loop {
if i == 3 {
break Ok("Max number of retries".to_string());
}
i = i + 1;
// Set a retry savepoint
// See https://www.cockroachlabs.com/docs/stable/advanced-client-side-transaction-retries
let mut sp = txn.savepoint("cockroach_restart").await?;
match self.transfer(&mut sp, &data).await {
Ok(e) => {
if e.is_empty() {
sp.commit().await?;
break Ok("".to_string());
} else {
break Ok(e);
}
}
Err(ref err)
if err
.code()
.map(|e| *e == SqlState::T_R_SERIALIZATION_FAILURE)
.unwrap_or(false) => {
println!("T_R_SERIALIZATION_FAILURE {:?}", err);
}
r => break r,
}
} {
Ok(t) => {
if t.is_empty() {
txn.commit().await.map_err(|e| AppError::DatasourceError(format!("Error on commit {}", e)))
} else {
Err(AppError::ValidationError(t))
}
}
Err(e) => Err(AppError::DatasourceError(e.to_string()))
}
}

async fn transfer(&self, txn: &mut Transaction, data: &WalletTransferEntity) -> Result {
let from_balance: Decimal = txn.query_one(r#"SELECT balance FROM wallet_accounts WHERE user_id = $1"#, &[&data.from_user_id]).await?.get(0);

if from_balance < data.amount {
return Ok(
"No Enough balance".to_string()
);
}

// Perform the transfer.
txn.execute(
"UPDATE wallet_accounts SET balance = balance - $1 WHERE user_id = $2",
&[&data.amount, &data.from_user_id],
).await?;
txn.execute(
"UPDATE wallet_accounts SET balance = balance + $1 WHERE user_id = $2",
&[&data.amount, &data.to_user_id],
).await?;
Ok("".to_string())
}
}
```

Thanks

Contributor guide

No contributing guide indexed for this repository

Research direction

The issue provides a Rust implementation of TransactionRepository::make_transaction and transfer using Tokio Postgres and deadpool_postgres, but names no repository files or tests. Start by comparing the snippet with the repository's existing example and the Tokio Postgres transaction documentation. Done means the implementation has a clear correctness assessment or the specific changes needed are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgres, rust
Domain
backend, databases
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.