Session store: implement create with id-collision retry

Silences tower-sessions' warning about the default create and never
overwrites an existing row on a session id collision.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
This commit is contained in:
2026-09-03 18:22:41 +00:00
co-authored by Claude Fable 5.1
parent eb960f1b57
commit 9b1c137c80
+16
View File
@@ -54,6 +54,22 @@ fn store_error(error: impl std::fmt::Display) -> session_store::Error {
#[async_trait] #[async_trait]
impl SessionStore for SqliteSessionStore { impl SessionStore for SqliteSessionStore {
/// Insert a brand-new record, drawing a fresh id on the (astronomically
/// unlikely) collision with an existing row instead of overwriting it.
async fn create(&self, record: &mut Record) -> session_store::Result<()> {
loop {
let exists: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM sessions WHERE id = ?")
.bind(record.id.to_string())
.fetch_one(&self.pool)
.await
.map_err(store_error)?;
if exists == 0 {
return self.save(record).await;
}
record.id = Id::default();
}
}
async fn save(&self, record: &Record) -> session_store::Result<()> { async fn save(&self, record: &Record) -> session_store::Result<()> {
let data = serde_json::to_string(&record.data).map_err(store_error)?; let data = serde_json::to_string(&record.data).map_err(store_error)?;
let user_id = record let user_id = record