forked from Keelrleek/SoulStream
community: every ledger takes its write lock, so the inbox check can no longer land on top of a friend accept
This commit is contained in:
1 parent
07227a90a7
commit
4d03cf849b
6 files changed
+89
-29
No files matched your search
@@ -29,6 +29,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tauri::{Emitter, Manager, State};
|
||||
|
||||
use crate::inbox::{self, Cargo, ShareCargo};
|
||||
use crate::ledger as ledger_lock;
|
||||
use crate::persona;
|
||||
use crate::pipeline::LibraryState;
|
||||
use crate::playlist_formats::{ParsedEntry, ParsedPlaylist};
|
||||
@@ -170,8 +171,11 @@ fn path(app: &tauri::AppHandle) -> Result<PathBuf, String> {
|
||||
.app_data_dir()
|
||||
.map_err(|e| e.to_string())?
|
||||
.join("freenet")
|
||||
.join("playlists-ledger.json"))
|
||||
.join(LEDGER_FILE))
|
||||
}
|
||||
/// Both the file the ledger lives in and the key its write lock is taken on.
|
||||
const LEDGER_FILE: &str = "playlists-ledger.json";
|
||||
|
||||
fn load(app: &tauri::AppHandle) -> Ledger {
|
||||
path(app)
|
||||
.ok()
|
||||
@@ -231,6 +235,7 @@ pub async fn publish(app: &tauri::AppHandle, lib: &LibraryState, playlist_id: i6
|
||||
if items.len() > pl::MAX_ENTRIES {
|
||||
return Err(format!("{} entries is over the {} cap", items.len(), pl::MAX_ENTRIES));
|
||||
}
|
||||
let _guard = ledger_lock::hold(LEDGER_FILE).await;
|
||||
let mut ledger = load(app);
|
||||
let key = playlist_id.to_string();
|
||||
let prev = ledger.published.get(&key).cloned();
|
||||
@@ -331,6 +336,7 @@ pub async fn publish(app: &tauri::AppHandle, lib: &LibraryState, playlist_id: i6
|
||||
pub async fn withdraw(app: &tauri::AppHandle, playlist_id: i64) -> Result<Published, String> {
|
||||
let adapter = app.state::<AppState>().freenet.clone();
|
||||
let owner = own_key(app).await?;
|
||||
let _guard = ledger_lock::hold(LEDGER_FILE).await;
|
||||
let mut ledger = load(app);
|
||||
let key = playlist_id.to_string();
|
||||
let prev = ledger.published.get(&key).cloned().ok_or("that playlist was never published")?;
|
||||
@@ -564,8 +570,9 @@ pub async fn send(app: &tauri::AppHandle, username: &str, playlist_id: i64) -> R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn keep_card(app: &tauri::AppHandle, card: ShareCard) {
|
||||
async fn keep_card(app: &tauri::AppHandle, card: ShareCard) {
|
||||
let who = if card.from_username.is_empty() { card.from_key.clone() } else { card.from_username.clone() };
|
||||
let _guard = ledger_lock::hold(LEDGER_FILE).await;
|
||||
let mut ledger = load(app);
|
||||
ledger.inbox.retain(|c| c.id != card.id);
|
||||
ledger.inbox.push(card);
|
||||
@@ -577,7 +584,7 @@ fn keep_card(app: &tauri::AppHandle, card: ShareCard) {
|
||||
}
|
||||
|
||||
/// Sealed cargo from inbox.rs: the envelope's signer is the sender.
|
||||
pub(crate) fn on_inbox_share(app: &tauri::AppHandle, sender: [u8; 32], s: ShareCargo) {
|
||||
pub(crate) async fn on_inbox_share(app: &tauri::AppHandle, sender: [u8; 32], s: ShareCargo) {
|
||||
let from_key = b58(&sender);
|
||||
let from_username = crate::slsk_link::username_for_key(app, &from_key).unwrap_or_default();
|
||||
keep_card(
|
||||
@@ -593,7 +600,8 @@ pub(crate) fn on_inbox_share(app: &tauri::AppHandle, sender: [u8; 32], s: ShareC
|
||||
entry_count: s.entry_count,
|
||||
received_at: now_secs(),
|
||||
},
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// The event pump hands private messages here after the link and friend
|
||||
@@ -603,9 +611,7 @@ pub fn intercept_pm(app: &tauri::AppHandle, from: &str, message: &str) -> bool {
|
||||
use base64::Engine;
|
||||
let Ok(bytes) = base64::engine::general_purpose::STANDARD.decode(rest.trim()) else { return true };
|
||||
let Ok(r) = bincode::deserialize::<ShareRef>(&bytes) else { return true };
|
||||
keep_card(
|
||||
app,
|
||||
ShareCard {
|
||||
let card = ShareCard {
|
||||
id: format!("{}:{}:{}", normalize_username(from), b58(&r.owner), b58(&r.playlist_uuid)),
|
||||
from_username: from.to_string(),
|
||||
from_key: String::new(),
|
||||
@@ -615,8 +621,11 @@ pub fn intercept_pm(app: &tauri::AppHandle, from: &str, message: &str) -> bool {
|
||||
name: cap(&r.name, pl::MAX_NAME_BYTES),
|
||||
entry_count: r.entry_count,
|
||||
received_at: now_secs(),
|
||||
},
|
||||
);
|
||||
};
|
||||
// Its own task: keeping a card now takes the ledger, and an inline await
|
||||
// here would block the event pump.
|
||||
let app = app.clone();
|
||||
tauri::async_runtime::spawn(async move { keep_card(&app, card).await });
|
||||
true
|
||||
}
|
||||
|
||||
@@ -664,7 +673,8 @@ pub fn shares_inbox(app: tauri::AppHandle) -> Vec<ShareCard> {
|
||||
v
|
||||
}
|
||||
#[tauri::command]
|
||||
pub fn share_dismiss(app: tauri::AppHandle, id: String) -> Result<(), String> {
|
||||
pub async fn share_dismiss(app: tauri::AppHandle, id: String) -> Result<(), String> {
|
||||
let _guard = ledger_lock::hold(LEDGER_FILE).await;
|
||||
let mut ledger = load(&app);
|
||||
ledger.inbox.retain(|c| c.id != id);
|
||||
save(&app, &ledger)
|
||||
|
||||
Reference in new issue
Block a user