Skip to content

Commit e7eb02d

Browse files
authored
Merge pull request #110 from SM-Obstacle/105-smaller-transactions
Reduce transactions scope
2 parents 0f5429d + efcc01d commit e7eb02d

File tree

24 files changed

+715
-496
lines changed

24 files changed

+715
-496
lines changed

crates/admin/src/leaderboard.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use records_lib::{Database, RedisConnection, leaderboard, map, must, time::Time};
1+
use records_lib::{Database, RedisPool, leaderboard, map, must, time::Time};
22
use sea_orm::{ConnectionTrait, StreamTrait};
33

44
#[derive(clap::Subcommand)]
@@ -34,13 +34,13 @@ enum Map {
3434

3535
async fn mariadb_lb<C: ConnectionTrait + StreamTrait>(
3636
conn: &C,
37-
redis_conn: &mut RedisConnection,
37+
redis_pool: &RedisPool,
3838
map_id: u32,
3939
offset: Option<i32>,
4040
limit: Option<i32>,
4141
) -> anyhow::Result<()> {
4242
let leaderboard =
43-
leaderboard::leaderboard(conn, redis_conn, map_id, offset, limit, Default::default())
43+
leaderboard::leaderboard(conn, redis_pool, map_id, offset, limit, Default::default())
4444
.await?
4545
.into_iter()
4646
.enumerate();
@@ -65,21 +65,19 @@ async fn mariadb_lb<C: ConnectionTrait + StreamTrait>(
6565

6666
async fn full<C: ConnectionTrait + StreamTrait>(
6767
conn: &C,
68-
redis_conn: &mut RedisConnection,
68+
redis_pool: &RedisPool,
6969
cmd: FullCmd,
7070
) -> anyhow::Result<()> {
7171
let map = match cmd.map {
7272
Map::MapId { map_id } => map::get_map_from_id(conn, map_id).await?,
7373
Map::MapUid { map_uid } => must::have_map(conn, &map_uid).await?,
7474
};
75-
mariadb_lb(conn, redis_conn, map.id, cmd.offset, cmd.limit).await
75+
mariadb_lb(conn, redis_pool, map.id, cmd.offset, cmd.limit).await
7676
}
7777

7878
pub async fn leaderboard(db: Database, cmd: LbCommand) -> anyhow::Result<()> {
79-
let mut redis_conn = db.redis_pool.get().await?;
80-
8179
match cmd {
82-
LbCommand::Full(full_cmd) => full(&db.sql_conn, &mut redis_conn, full_cmd).await?,
80+
LbCommand::Full(full_cmd) => full(&db.sql_conn, &db.redis_pool, full_cmd).await?,
8381
}
8482

8583
Ok(())

crates/admin/src/populate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use records_lib::{
1414
mappack::{self, AnyMappackId},
1515
must,
1616
redis_key::{cached_key, mappack_key},
17+
sync,
1718
time::Time,
18-
transaction,
1919
};
2020
use sea_orm::{
2121
ActiveValue::{NotSet, Set},
@@ -234,7 +234,7 @@ async fn run_populate<C: TransactionTrait + ConnectionTrait>(
234234
.await?;
235235
}
236236

237-
match transaction::within(conn, async |txn| {
237+
match sync::transaction(conn, async |txn| {
238238
tracing::info!("Clearing old content");
239239
clear::clear_content(txn, redis_conn, event, edition).await?;
240240

@@ -306,7 +306,7 @@ pub async fn populate(
306306
tracing::info!("Filling mappack in the Redis database...");
307307
mappack::update_mappack(
308308
&db.sql_conn,
309-
&mut redis_conn,
309+
&db.redis_pool,
310310
AnyMappackId::Event(&event, &edition),
311311
Default::default(),
312312
)

crates/game_api/src/http.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,7 @@ async fn overview(
215215
.await
216216
.with_api_err()?;
217217

218-
let mut redis_conn = db.redis_pool.get().await.with_api_err()?;
219-
220-
let res = overview::overview(
221-
&db.sql_conn,
222-
&mut redis_conn,
223-
&query.login,
224-
&map,
225-
Default::default(),
226-
)
227-
.await?;
218+
let res = overview::overview(db.0, &query.login, &map, Default::default()).await?;
228219

229220
utils::json(res)
230221
}

crates/game_api/src/http/event.rs

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use actix_web::{
44
Responder, Scope,
55
web::{self, Path},
66
};
7+
use deadpool_redis::redis::AsyncCommands as _;
78
use entity::{
89
event_edition, event_edition_maps, event_edition_records, global_event_records, global_records,
910
in_game_event_edition_params, maps, players, records,
@@ -12,16 +13,18 @@ use entity::{
1213
use futures::TryStreamExt;
1314
use itertools::Itertools;
1415
use records_lib::{
15-
Database, Expirable as _, NullableInteger, NullableReal, NullableText, RedisConnection,
16+
Database, Expirable as _, NullableInteger, NullableReal, NullableText, RedisPool,
1617
error::RecordsError,
1718
event::{self, EventMap},
1819
opt_event::OptEvent,
19-
player, transaction,
20+
player,
21+
redis_key::alone_map_key,
22+
sync,
2023
};
2124
use sea_orm::{
2225
ActiveValue::Set,
2326
ColumnTrait as _, ConnectionTrait, EntityTrait, FromQueryResult, QueryFilter, QueryOrder,
24-
QuerySelect, QueryTrait as _, RelationTrait as _, StreamTrait,
27+
QuerySelect, QueryTrait as _, RelationTrait as _, TransactionTrait,
2528
prelude::Expr,
2629
sea_query::{Asterisk, Func, Query},
2730
};
@@ -771,8 +774,6 @@ async fn edition_overview(
771774
path: Path<(String, u32)>,
772775
query: overview::OverviewReq,
773776
) -> RecordsResult<impl Responder> {
774-
let mut redis_conn = db.0.redis_pool.get().await.with_api_err()?;
775-
776777
let (event, edition) = path.into_inner();
777778

778779
let (event, edition, EventMap { map, .. }) = records_lib::must::have_event_edition_with_map(
@@ -788,14 +789,7 @@ async fn edition_overview(
788789
return Err(ApiErrorKind::EventHasExpired(event.handle, edition.id));
789790
}
790791

791-
let res = overview::overview(
792-
&db.sql_conn,
793-
&mut redis_conn,
794-
&query.login,
795-
&map,
796-
OptEvent::new(&event, &edition),
797-
)
798-
.await?;
792+
let res = overview::overview(db.0, &query.login, &map, OptEvent::new(&event, &edition)).await?;
799793

800794
utils::json(res)
801795
}
@@ -822,26 +816,25 @@ async fn edition_finished(
822816
struct EditionFinishedParams<'a> {
823817
player_login: &'a str,
824818
map: &'a maps::Model,
825-
event_id: u32,
826-
edition_id: u32,
827819
original_map_id: Option<u32>,
828820
inner_params: ExpandedInsertRecordParams<'a>,
829821
}
830822

831-
async fn edition_finished_impl<C: ConnectionTrait + StreamTrait>(
823+
async fn edition_finished_impl<C>(
832824
conn: &C,
833-
redis_conn: &mut RedisConnection,
825+
redis_pool: &RedisPool,
834826
EditionFinishedParams {
835827
player_login,
836828
map,
837-
event_id,
838-
edition_id,
839829
original_map_id,
840830
inner_params: params,
841831
}: EditionFinishedParams<'_>,
842-
) -> RecordsResult<pf::FinishedOutput> {
843-
// Then we insert the record for the global records
844-
let res = pf::finished(conn, redis_conn, params, player_login, map).await?;
832+
) -> RecordsResult<pf::FinishedOutput>
833+
where
834+
C: ConnectionTrait + TransactionTrait,
835+
{
836+
// We insert the record for the global records
837+
let res = pf::finished(conn, redis_pool, params, player_login, map).await?;
845838

846839
if let Some(original_map_id) = original_map_id {
847840
// Get the previous time of the player on the original map to check if it's a PB
@@ -852,24 +845,37 @@ async fn edition_finished_impl<C: ConnectionTrait + StreamTrait>(
852845
let is_pb =
853846
time_on_previous.is_none() || time_on_previous.is_some_and(|t| t > params.body.time);
854847

855-
// Here, we don't provide the event instances, because we don't want to save in event mode.
856-
pf::insert_record(
857-
conn,
858-
redis_conn,
859-
ExpandedInsertRecordParams {
860-
event: Default::default(),
861-
..params
862-
},
863-
original_map_id,
864-
res.player_id,
865-
Some(res.record_id),
866-
is_pb,
867-
)
848+
sync::transaction(conn, async |txn| {
849+
// Here, we don't provide the event instances, because we don't want to save in event mode.
850+
pf::insert_record(
851+
txn,
852+
ExpandedInsertRecordParams {
853+
event: Default::default(),
854+
..params
855+
},
856+
original_map_id,
857+
res.player_id,
858+
Some(res.record_id),
859+
)
860+
.await
861+
})
868862
.await?;
869-
}
870863

871-
// Then we insert it for the event edition records.
872-
insert_event_record(conn, res.record_id, event_id, edition_id).await?;
864+
// Update the rank on the original map
865+
if is_pb {
866+
let _: () = redis_pool
867+
.get()
868+
.await
869+
.with_api_err()?
870+
.zadd(
871+
alone_map_key(original_map_id),
872+
res.player_id,
873+
params.body.time,
874+
)
875+
.await
876+
.with_api_err()?;
877+
}
878+
}
873879

874880
Ok(res)
875881
}
@@ -901,19 +907,11 @@ pub async fn edition_finished_at(
901907
)
902908
.await?;
903909

904-
let mut redis_conn = db.0.redis_pool.get().await.with_api_err()?;
905-
906910
// The edition is transparent, so we save the record for the map directly.
907911
if edition.is_transparent != 0 {
908-
let res = super::player::finished_at(
909-
&db.sql_conn,
910-
&mut redis_conn,
911-
mode_version,
912-
login,
913-
body,
914-
at,
915-
)
916-
.await?;
912+
let res =
913+
super::player::finished_at(&db.sql_conn, &db.redis_pool, mode_version, login, body, at)
914+
.await?;
917915
return Ok(utils::Either::Left(res));
918916
}
919917

@@ -923,24 +921,19 @@ pub async fn edition_finished_at(
923921
return Err(ApiErrorKind::EventHasExpired(event.handle, edition.id));
924922
}
925923

926-
let res: pf::FinishedOutput = transaction::within(&db.sql_conn, async |txn| {
927-
let params = EditionFinishedParams {
928-
player_login: &login,
929-
map: &map,
930-
event_id: event.id,
931-
edition_id: edition.id,
932-
original_map_id,
933-
inner_params: ExpandedInsertRecordParams {
934-
body: &body.rest,
935-
at,
936-
event: OptEvent::new(&event, &edition),
937-
mode_version,
938-
},
939-
};
924+
let params = EditionFinishedParams {
925+
player_login: &login,
926+
map: &map,
927+
original_map_id,
928+
inner_params: ExpandedInsertRecordParams {
929+
body: &body.rest,
930+
at,
931+
event: OptEvent::new(&event, &edition),
932+
mode_version,
933+
},
934+
};
940935

941-
edition_finished_impl(txn, &mut redis_conn, params).await
942-
})
943-
.await?;
936+
let res = edition_finished_impl(&db.sql_conn, &db.redis_pool, params).await?;
944937

945938
json(res.res).map(utils::Either::Right)
946939
}

0 commit comments

Comments
 (0)