Skip to content

Commit 574f355

Browse files
authored
fix: preserve the uid ordering by sorting in reverse (#2017)
for the case when created_ats are identical (likely just in tests) we want the uid DESC from the get_users query used as a tie breaker Closes STOR-462
1 parent efb70a1 commit 574f355

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

tokenserver-db-common/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ mod error;
55
pub mod params;
66
pub mod results;
77

8-
use std::time::{Duration, SystemTime, UNIX_EPOCH};
8+
use std::{
9+
cmp,
10+
time::{Duration, SystemTime, UNIX_EPOCH},
11+
};
912

1013
use async_trait::async_trait;
1114
use syncserver_common::Metrics;
@@ -127,8 +130,8 @@ pub trait Db {
127130
old_client_states: vec![],
128131
})
129132
} else {
130-
raw_users.sort_by_key(|raw_user| (raw_user.generation, raw_user.created_at));
131-
raw_users.reverse();
133+
raw_users
134+
.sort_by_key(|raw_user| cmp::Reverse((raw_user.generation, raw_user.created_at)));
132135

133136
// The user with the greatest `generation` and `created_at` is the current user
134137
let raw_user = raw_users[0].clone();

tokenserver-db/src/tests.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,80 @@ async fn test_correct_created_at_used_during_user_retrieval() -> DbResult<()> {
11921192
Ok(())
11931193
}
11941194

1195+
#[tokio::test]
1196+
async fn test_latest_created_at() -> DbResult<()> {
1197+
let pool = db_pool().await?;
1198+
let mut db = pool.get().await?;
1199+
1200+
let service_id = db
1201+
.get_service_id(params::GetServiceId {
1202+
service: "sync-1.5".to_owned(),
1203+
})
1204+
.await?
1205+
.id;
1206+
1207+
// Add a node
1208+
let node_id = db
1209+
.post_node(params::PostNode {
1210+
service_id,
1211+
node: "https://node1".to_owned(),
1212+
current_load: 0,
1213+
capacity: 100,
1214+
available: 100,
1215+
..Default::default()
1216+
})
1217+
.await?
1218+
.id;
1219+
1220+
let email = "test_user";
1221+
let now = SystemTime::now()
1222+
.duration_since(UNIX_EPOCH)
1223+
.unwrap()
1224+
.as_millis() as i64;
1225+
1226+
// Add a user marked as replaced
1227+
let post_user = params::PostUser {
1228+
service_id,
1229+
email: email.to_owned(),
1230+
node_id,
1231+
client_state: "aaaa".to_owned(),
1232+
generation: 1234,
1233+
keys_changed_at: Some(1234),
1234+
created_at: now,
1235+
};
1236+
let uid1 = db.post_user(post_user.clone()).await?.uid;
1237+
db.replace_user(params::ReplaceUser {
1238+
uid: uid1,
1239+
service_id,
1240+
replaced_at: now,
1241+
})
1242+
.await?;
1243+
1244+
// User's latest record w/ a new client_state, otherwise identical to the
1245+
// replaced record (even created_at)
1246+
let uid2 = db
1247+
.post_user(params::PostUser {
1248+
client_state: "bbbb".to_owned(),
1249+
..post_user
1250+
})
1251+
.await?
1252+
.uid;
1253+
assert_ne!(uid1, uid2);
1254+
1255+
// Should return the latest record even with the identical created_at
1256+
let user = db
1257+
.get_or_create_user(params::GetOrCreateUser {
1258+
service_id,
1259+
email: email.to_owned(),
1260+
..Default::default()
1261+
})
1262+
.await?;
1263+
assert_eq!(user.uid, uid2);
1264+
assert_eq!(user.client_state, "bbbb");
1265+
1266+
Ok(())
1267+
}
1268+
11951269
#[tokio::test]
11961270
async fn test_get_spanner_node() -> DbResult<()> {
11971271
let pool = db_pool().await?;

0 commit comments

Comments
 (0)