From 63bae0e0e5f646ebc5e3d1d9c12162789a39638a Mon Sep 17 00:00:00 2001 From: ntr Date: Mon, 15 Oct 2018 15:55:50 +1100 Subject: [PATCH] tx handled outside of rpc calls --- server/src/account.rs | 20 ++++++++-------- server/src/combat.rs | 10 +++----- server/src/cryp.rs | 6 +---- server/src/item.rs | 22 +++++++---------- server/src/rpc.rs | 56 ++++++++++++++++++++++++------------------- 5 files changed, 54 insertions(+), 60 deletions(-) diff --git a/server/src/account.rs b/server/src/account.rs index 43d683aa..fae0d333 100755 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -5,6 +5,8 @@ use rand::distributions::Alphanumeric; use std::iter; use serde_cbor::{from_slice}; +use postgres::transaction::Transaction; + use std::str; use net::Db; @@ -35,14 +37,14 @@ struct AccountEntry { // MAYBE // hash tokens with a secret -pub fn account_from_token(token: String, db: &Db) -> Result { +pub fn account_from_token(token: String, tx: &mut Transaction) -> Result { let query = " SELECT id, name, token FROM accounts WHERE token = $1; "; - let result = db + let result = tx .query(query, &[&token])?; let returned = match result.iter().next() { @@ -59,7 +61,7 @@ pub fn account_from_token(token: String, db: &Db) -> Result { return Ok(entry); } -pub fn account_create(params: AccountCreateParams, db: &Db) -> Result { +pub fn account_create(params: AccountCreateParams, tx: &mut Transaction) -> Result { let id = Uuid::new_v4(); if params.password.len() < PASSWORD_MIN_LEN { @@ -86,7 +88,6 @@ pub fn account_create(params: AccountCreateParams, db: &Db) -> Result Result Result { +pub fn account_login(params: AccountLoginParams, tx: &mut Transaction) -> Result { let query = " SELECT id, name, token, password FROM accounts WHERE name = $1; "; - let result = db + let result = tx .query(query, &[¶ms.name])?; let returned = match result.iter().next() { @@ -153,14 +153,14 @@ pub fn account_login(params: AccountLoginParams, db: &Db) -> Result Result, Error> { +pub fn account_cryps(tx: &mut Transaction, account: &Account) -> Result, Error> { let query = " SELECT data FROM cryps WHERE account = $1; "; - let result = db + let result = tx .query(query, &[&account.id])?; let cryps: Result, _> = result.iter().map(|row| { diff --git a/server/src/combat.rs b/server/src/combat.rs index fe4d51ac..7bc28f69 100755 --- a/server/src/combat.rs +++ b/server/src/combat.rs @@ -2,10 +2,10 @@ use rand::prelude::*; use serde_cbor::{from_slice}; // Db Commons +use postgres::transaction::Transaction; use failure::Error; use failure::err_msg; -use net::Db; use account::Account; use rpc::{CombatPveParams}; @@ -92,7 +92,7 @@ fn generate_mob(plr: &Cryp) -> Cryp { } -pub fn pve(params: CombatPveParams, db: &Db, account: &Account) -> Result { +pub fn pve(params: CombatPveParams, tx: &mut Transaction, account: &Account) -> Result { let query = " SELECT * FROM cryps @@ -100,8 +100,6 @@ pub fn pve(params: CombatPveParams, db: &Db, account: &Account) -> Result Result Result Result { +pub fn cryp_spawn(params: CrypSpawnParams, tx: &mut Transaction, account: &Account) -> Result { let cryp = Cryp::new() .named(¶ms.name) .level(1) @@ -229,8 +229,6 @@ pub fn cryp_spawn(params: CrypSpawnParams, db: &Db, account: &Account) -> Result RETURNING id, account; "; - let tx = db.transaction()?; - let result = tx .query(query, &[&cryp.id, &account.id, &cryp_bytes])?; @@ -238,8 +236,6 @@ pub fn cryp_spawn(params: CrypSpawnParams, db: &Db, account: &Account) -> Result println!("{:?} spawned cryp {:}", account.id, cryp.id); - tx.commit()?; - return Ok(cryp); } diff --git a/server/src/item.rs b/server/src/item.rs index b8729c75..b158e7a5 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -1,14 +1,14 @@ -use account::Account; -use uuid::Uuid; use serde_cbor::{from_slice, to_vec}; +use uuid::Uuid; -use net::Db; use postgres::transaction::Transaction; +use failure::Error; +use failure::err_msg; + +use account::Account; use rpc::{ItemUseParams}; use cryp::{cryp_get, cryp_write}; -use failure::Error; -use failure::err_msg; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum ItemAction { @@ -67,7 +67,7 @@ pub fn item_create(item: Item, tx: &mut Transaction, account: &Account) -> Resul return Ok(item); } -pub fn item_use(params: ItemUseParams, db: &Db, account: &Account) -> Result<(), Error> { +pub fn item_use(params: ItemUseParams, tx: &mut Transaction, account: &Account) -> Result<(), Error> { let query = " SELECT data FOR UPDATE @@ -76,8 +76,6 @@ pub fn item_use(params: ItemUseParams, db: &Db, account: &Account) -> Result<(), AND account = $2; "; - let mut tx = db.transaction()?; - let result = tx .query(query, &[¶ms.item, &account.id])?; @@ -86,21 +84,19 @@ pub fn item_use(params: ItemUseParams, db: &Db, account: &Account) -> Result<(), let item_bytes: Vec = returned.get(0); let mut item = from_slice::(&item_bytes)?; - item.apply(&mut tx, params.target)?; - - tx.commit()?; + item.apply(tx, params.target)?; return Ok(()); } -pub fn items_list(db: &Db, account: &Account) -> Result, Error> { +pub fn items_list(tx: &mut Transaction, account: &Account) -> Result, Error> { let query = " SELECT data FROM items WHERE account = $1; "; - let result = db + let result = tx .query(query, &[&account.id])?; let items: Result, _> = result.iter().map(|row| { diff --git a/server/src/rpc.rs b/server/src/rpc.rs index eb60f8ab..223bb0d3 100755 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -1,6 +1,7 @@ use tungstenite::Message; use tungstenite::protocol::WebSocket; use tungstenite::Message::Binary; +use postgres::transaction::Transaction; use std::net::{TcpStream}; use serde_cbor::{from_slice, to_vec}; @@ -25,9 +26,10 @@ impl Rpc { // cast the msg to this type to receive method name match from_slice::(&data) { Ok(v) => { + let mut tx = db.transaction()?; let account: Option = match v.token { - Some(t) => Some(account_from_token(t, &db)?), + Some(t) => Some(account_from_token(t, &mut tx)?), None => None, }; @@ -35,17 +37,21 @@ impl Rpc { // now we have the method name // match on that to determine what fn to call - match v.method.as_ref() { - "cryp_spawn" => Rpc::cryp_spawn(data, db, account), - "combat_pve" => Rpc::combat_pve(data, db, account, client), - "account_create" => Rpc::account_create(data, db), - "account_login" => Rpc::account_login(data, db), - "account_cryps" => Rpc::account_cryps(db, account), - "item_list" => Rpc::item_list(db, account), - "item_use" => Rpc::item_use(data, db, account), + let response = match v.method.as_ref() { + "cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account), + "combat_pve" => Rpc::combat_pve(data, &mut tx, account, client), + "account_create" => Rpc::account_create(data, &mut tx), + "account_login" => Rpc::account_login(data, &mut tx), + "account_cryps" => Rpc::account_cryps(&mut tx, account), + "item_list" => Rpc::item_list(&mut tx, account), + "item_use" => Rpc::item_use(data, &mut tx, account), _ => Err(err_msg("unknown method")), - } + }; + + tx.commit()?; + + return response; }, Err(_e) => Err(err_msg("invalid message")), } @@ -59,7 +65,7 @@ impl Rpc { } } - fn combat_pve(data: Vec, db: &Db, account: Option, client: &mut WebSocket) -> Result { + fn combat_pve(data: Vec, tx: &mut Transaction, account: Option, client: &mut WebSocket) -> Result { let a = match account { Some(a) => a, None => return Err(err_msg("auth required")), @@ -69,24 +75,24 @@ impl Rpc { let battle_response = RpcResponse { method: "battle_state".to_string(), - params: RpcResult::Pve(pve(msg.params, db, &a)?) + params: RpcResult::Pve(pve(msg.params, tx, &a)?) }; Rpc::send_msg(client, RpcResponse { method: "account_cryps".to_string(), - params: RpcResult::CrypList(account_cryps(db, &a)?) + params: RpcResult::CrypList(account_cryps(tx, &a)?) })?; return Ok(battle_response); } - fn cryp_spawn(data: Vec, db: &Db, account: Option) -> Result { + fn cryp_spawn(data: Vec, tx: &mut Transaction, account: Option) -> Result { match from_slice::(&data) { Ok(v) => { match account { Some(a) => Ok(RpcResponse { method: v.method, - params: RpcResult::SpawnCryp(cryp_spawn(v.params, db, &a)?) + params: RpcResult::SpawnCryp(cryp_spawn(v.params, tx, &a)?) }), None => Err(err_msg("auth required")), } @@ -95,53 +101,53 @@ impl Rpc { } } - fn account_create(data: Vec, db: &Db) -> Result { + fn account_create(data: Vec, tx: &mut Transaction) -> Result { match from_slice::(&data) { Ok(v) => Ok(RpcResponse { method: v.method, - params: RpcResult::Account(account_create(v.params, db)?) + params: RpcResult::Account(account_create(v.params, tx)?) }), Err(_e) => Err(err_msg("invalid params")), } } - fn account_login(data: Vec, db: &Db) -> Result { + fn account_login(data: Vec, tx: &mut Transaction) -> Result { match from_slice::(&data) { Ok(v) => Ok(RpcResponse { method: v.method, - params: RpcResult::Account(account_login(v.params, db)?) + params: RpcResult::Account(account_login(v.params, tx)?) }), Err(_e) => Err(err_msg("invalid params")), } } - fn account_cryps(db: &Db, account: Option) -> Result { + fn account_cryps(tx: &mut Transaction, account: Option) -> Result { match account { Some(a) => Ok(RpcResponse { method: "account_cryps".to_string(), - params: RpcResult::CrypList(account_cryps(db, &a)?) + params: RpcResult::CrypList(account_cryps(tx, &a)?) }), None => Err(err_msg("auth required")), } } - fn item_list(db: &Db, account: Option) -> Result { + fn item_list(tx: &mut Transaction, account: Option) -> Result { match account { Some(a) => Ok(RpcResponse { method: "item_list".to_string(), - params: RpcResult::ItemList(items_list(db, &a)?) + params: RpcResult::ItemList(items_list(tx, &a)?) }), None => Err(err_msg("auth required")), } } - fn item_use(data: Vec, db: &Db, account: Option) -> Result { + fn item_use(data: Vec, tx: &mut Transaction, account: Option) -> Result { match from_slice::(&data) { Ok(v) => { match account { Some(a) => Ok(RpcResponse { method: v.method, - params: RpcResult::ItemUse(item_use(v.params, db, &a)?) + params: RpcResult::ItemUse(item_use(v.params, tx, &a)?) }), None => Err(err_msg("auth required")), }