Stop deleting logo blob when switching

This also means we can clean up the last blob operations that were per cid rather than user+cid 🪓

We should be setting ourselves up to be able to go garbage collect blobs safely so deleting the logo blobs manually won't matter anyway.
This commit is contained in:
Johanna Larsson
2026-09-12 15:34:46 +00:00
committed by Tangled
parent 2fc5f2e308
commit 2088f59197
8 changed files with 3 additions and 157 deletions
@@ -1,14 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM blobs WHERE cid = $1",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text"
]
},
"nullable": []
},
"hash": "d2990ce7f233d2489bb36a63920571c9f454a0605cc463829693d581bc0dce12"
}
-42
View File
@@ -1,10 +1,8 @@
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
use tracing::{error, warn};
use tranquil_pds::api::error::{ApiError, DbResultExt};
use tranquil_pds::auth::{Admin, Auth};
use tranquil_pds::state::AppState;
use tranquil_types::CidLink;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
@@ -183,46 +181,6 @@ pub async fn update_server_config(
}
if let Some(ref logo_cid) = req.logo_cid {
let old_logo_cid = state
.repos
.infra
.get_server_config("logo_cid")
.await
.ok()
.flatten();
let should_delete_old = match (&old_logo_cid, logo_cid.is_empty()) {
(Some(old), true) => Some(old.clone()),
(Some(old), false) if old != logo_cid => Some(old.clone()),
_ => None,
};
if let Some(old_cid_str) = should_delete_old {
match CidLink::new(old_cid_str) {
Ok(old_cid) => {
if let Ok(Some(storage_key)) = state
.repos
.infra
.get_blob_storage_key_by_cid(&old_cid)
.await
{
if let Err(e) = state.blob_store.delete(&storage_key).await {
error!("Failed to delete old logo blob from storage: {:?}", e);
}
if let Err(e) = state.repos.infra.delete_blob_by_cid(&old_cid).await {
error!("Failed to delete old logo blob record: {:?}", e);
}
}
}
Err(e) => {
warn!(
"Old logo CID in database is invalid, skipping cleanup: {:?}",
e
);
}
}
}
if logo_cid.is_empty() {
state
.repos
+1 -5
View File
@@ -1,7 +1,7 @@
use async_trait::async_trait;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use tranquil_types::{CidLink, Did, Handle, InviteCode};
use tranquil_types::{Did, Handle, InviteCode};
use uuid::Uuid;
use crate::DbError;
@@ -417,10 +417,6 @@ pub trait InfraRepository: Send + Sync {
async fn delete_server_config(&self, key: &str) -> Result<(), DbError>;
async fn get_blob_storage_key_by_cid(&self, cid: &CidLink) -> Result<Option<String>, DbError>;
async fn delete_blob_by_cid(&self, cid: &CidLink) -> Result<(), DbError>;
async fn get_admin_account_info_by_did(
&self,
did: &Did,
+1 -22
View File
@@ -7,7 +7,7 @@ use tranquil_db_traits::{
InviteCodeSortOrder, InviteCodeState, InviteCodeUse, NotificationHistoryRow, PlcTokenInfo,
QueuedComms, ReservedSigningKey, ReservedSigningKeyFull, ValidatedInviteCode,
};
use tranquil_types::{CidLink, Did, InviteCode};
use tranquil_types::{Did, InviteCode};
use uuid::Uuid;
use super::col;
@@ -1010,27 +1010,6 @@ impl InfraRepository for PostgresInfraRepository {
Ok(())
}
async fn get_blob_storage_key_by_cid(&self, cid: &CidLink) -> Result<Option<String>, DbError> {
let result = sqlx::query_scalar!(
"SELECT storage_key FROM blobs WHERE cid = $1 LIMIT 1",
cid.as_str()
)
.fetch_optional(&self.pool)
.await
.map_err(map_sqlx_error)?;
Ok(result)
}
async fn delete_blob_by_cid(&self, cid: &CidLink) -> Result<(), DbError> {
sqlx::query!("DELETE FROM blobs WHERE cid = $1", cid.as_str())
.execute(&self.pool)
.await
.map_err(map_sqlx_error)?;
Ok(())
}
async fn get_admin_account_info_by_did(
&self,
did: &Did,
@@ -2352,27 +2352,6 @@ impl<S: StorageIO + 'static> tranquil_db_traits::InfraRepository for MetastoreCl
recv(rx).await
}
async fn get_blob_storage_key_by_cid(&self, cid: &CidLink) -> Result<Option<String>, DbError> {
let (tx, rx) = oneshot::channel();
self.pool.send(MetastoreRequest::Infra(
InfraRequest::GetBlobStorageKeyByCid {
cid: cid.clone(),
tx,
},
))?;
recv(rx).await
}
async fn delete_blob_by_cid(&self, cid: &CidLink) -> Result<(), DbError> {
let (tx, rx) = oneshot::channel();
self.pool
.send(MetastoreRequest::Infra(InfraRequest::DeleteBlobByCid {
cid: cid.clone(),
tx,
}))?;
recv(rx).await
}
async fn get_admin_account_info_by_did(
&self,
did: &Did,
@@ -2009,14 +2009,6 @@ pub enum InfraRequest {
key: String,
tx: Tx<()>,
},
GetBlobStorageKeyByCid {
cid: CidLink,
tx: Tx<Option<String>>,
},
DeleteBlobByCid {
cid: CidLink,
tx: Tx<()>,
},
GetAdminAccountInfoByDid {
did: Did,
tx: Tx<Option<AdminAccountInfo>>,
@@ -2103,9 +2095,6 @@ impl InfraRequest {
| Self::GetDeletionRequestByDid { did, .. }
| Self::GetPlcTokensByDid { did, .. }
| Self::CountPlcTokensByDid { did, .. } => did_to_routing(did),
Self::GetBlobStorageKeyByCid { cid, .. } | Self::DeleteBlobByCid { cid, .. } => {
cid_to_routing(cid)
}
_ => Routing::Global,
}
}
@@ -4297,22 +4286,6 @@ fn dispatch_infra<S: StorageIO>(state: &HandlerState<S>, req: InfraRequest) {
.map_err(metastore_to_db);
let _ = tx.send(result);
}
InfraRequest::GetBlobStorageKeyByCid { cid, tx } => {
let result = state
.metastore
.infra_ops()
.get_blob_storage_key_by_cid(&cid)
.map_err(metastore_to_db);
let _ = tx.send(result);
}
InfraRequest::DeleteBlobByCid { cid, tx } => {
let result = state
.metastore
.infra_ops()
.delete_blob_by_cid(&cid)
.map_err(metastore_to_db);
let _ = tx.send(result);
}
InfraRequest::GetAdminAccountInfoByDid { did, tx } => {
let result = state
.metastore
@@ -6,7 +6,6 @@ use smallvec::SmallVec;
use uuid::Uuid;
use super::MetastoreError;
use super::blobs::{BlobContentValue, blob_by_cid_key};
use super::infra_schema::{
DeletionRequestValue, InviteCodeUseValue, InviteCodeValue, NotificationHistoryValue,
QueuedCommsValue, ReportValue, SigningKeyValue, account_pref_key, account_pref_prefix,
@@ -28,12 +27,11 @@ use tranquil_db_traits::{
InviteCodeState, InviteCodeUse, NotificationHistoryRow, PlcTokenInfo, QueuedComms,
ReservedSigningKey, ReservedSigningKeyFull, ValidatedInviteCode,
};
use tranquil_types::{CidLink, Did, Handle, InviteCode};
use tranquil_types::{Did, Handle, InviteCode};
pub struct InfraOps {
db: Database,
infra: Keyspace,
repo_data: Keyspace,
users: Keyspace,
user_hashes: Arc<UserHashMap>,
comms_seq: Arc<std::sync::atomic::AtomicU32>,
@@ -44,7 +42,6 @@ impl InfraOps {
pub fn new(
db: Database,
infra: Keyspace,
repo_data: Keyspace,
users: Keyspace,
user_hashes: Arc<UserHashMap>,
comms_seq: Arc<std::sync::atomic::AtomicU32>,
@@ -53,7 +50,6 @@ impl InfraOps {
Self {
db,
infra,
repo_data,
users,
user_hashes,
comms_seq,
@@ -1216,26 +1212,6 @@ impl InfraOps {
})
}
pub fn get_blob_storage_key_by_cid(
&self,
cid: &CidLink,
) -> Result<Option<String>, MetastoreError> {
let val: Option<BlobContentValue> = point_lookup(
&self.repo_data,
blob_by_cid_key(cid.as_str()).as_slice(),
BlobContentValue::deserialize,
"corrupt blob_content value",
)?;
Ok(val.map(|v| v.meta.storage_key))
}
pub fn delete_blob_by_cid(&self, cid: &CidLink) -> Result<(), MetastoreError> {
let _guard = self.counter_lock.lock();
self.repo_data
.remove(blob_by_cid_key(cid.as_str()).as_slice())
.map_err(MetastoreError::Fjall)
}
pub fn get_admin_account_info_by_did(
&self,
did: &Did,
@@ -395,7 +395,6 @@ impl Metastore {
infra_ops::InfraOps::new(
self.db.clone(),
self.partitions[Partition::Infra.index()].clone(),
self.partitions[Partition::RepoData.index()].clone(),
self.partitions[Partition::Users.index()].clone(),
Arc::clone(&self.user_hashes),
Arc::clone(&self.comms_seq),