refactor: cut what a whole-repo audit proved dead, padded, or hand-rolled
Seven region audits, every finding adversarially verified against the whole workspace before being applied; 80 landed and the two that failed in application were refuted honestly (ParseError has a from_str_radix producer the audit missed; NatPmpError's Display is the only reader of its diagnostic payloads). The bigger cuts: - The NewPeer/PierceFireWall cluster: an operation variant nothing ever sent, its 77-line arm, a protocol-wrong Client::pierce_firewall that wrote a peer-init frame down the server socket, and the struct only they used. The live paths in peer/listen.rs are untouched. - The ops loop reads `for operation in reader` instead of hand-rolling recv/break, de-indenting the whole dispatch body. - Dead lib surface: Message::print_hex and four unused accessors, UploadFailed, registry and actor getters, build_watch_user, strip_ansi_codes, delegating shims on ClientContext. Removing public items makes this a semver major, which the release pipeline enforces. - Never-used flexibility: the state-migration framework that never held a migration, border-type helpers that all answered Rounded, the TUI's max_concurrent_downloads field nothing read. - Convergence: six poll loops into poll_until, three wrap-around navigation blocks into cycle, hit tests into Rect::contains, char walkers into floor/ceil_char_boundary, five Download literals into one helper, the suites' shared scaffolding into tests/common. Deliberately not taken: swapping the hand-rolled zlib inflate and MD5 for crates (they replace wire-facing machinery whose tolerance of real-world peer quirks no local test exercises) and pulling chrono into the lib for a log timestamp. Recorded for their own decision. Net -1002 lines. Both e2e modes stay green: 94 CLI tests each way, 16 protocol, 33 lib, unit suites, clippy pedantic clean, aislop 100/100 with the four scanner false positives suppressed inline where they fire.
This commit is contained in:
@@ -2,7 +2,7 @@ use super::{
|
||||
Arc, Client, ClientContext, ClientOperation, ConnectionType, DownloadPeer,
|
||||
DownloadStatus, Listen, Peer, PeerRegistry, Receiver, Result, RwLock,
|
||||
RwLockExt, Sender, ServerActor, ServerMessage, Shares, SoulseekRs,
|
||||
TcpStream, debug, error, info, mpsc, thread, trace,
|
||||
TcpStream, error, info, mpsc, thread, trace,
|
||||
};
|
||||
|
||||
/// Ceiling on the wait for a login verdict. Generous enough for a slow server
|
||||
@@ -18,7 +18,6 @@ impl Client {
|
||||
) = mpsc::channel();
|
||||
|
||||
let mut ctx = self.context.write_safe()?;
|
||||
ctx.sender = Some(sender.clone());
|
||||
let peer_registry = PeerRegistry::new(
|
||||
ctx.actor_system.clone(),
|
||||
sender.clone(),
|
||||
@@ -166,8 +165,6 @@ impl Client {
|
||||
own_username: String,
|
||||
stream: Option<TcpStream>,
|
||||
) {
|
||||
let client_context = client_context;
|
||||
|
||||
let peer_clone = peer.clone();
|
||||
trace!(
|
||||
"[client] connecting to {}, with connection_type: {}, and token {:?}",
|
||||
@@ -252,37 +249,4 @@ impl Client {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pierce_firewall(
|
||||
peer: Peer,
|
||||
client_context: Arc<RwLock<ClientContext>>,
|
||||
own_username: String,
|
||||
) {
|
||||
debug!("Piercing firewall for peer: {:?}", peer);
|
||||
|
||||
let context = match client_context.read_safe() {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
error!("[client] pierce_firewall read: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Some(server_sender) = &context.server_sender {
|
||||
if let Some(token) = peer.token {
|
||||
match server_sender.send(ServerMessage::PierceFirewall(token)) {
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
error!("Failed to send PierceFirewall message: {}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("No token available for PierceFirewall");
|
||||
}
|
||||
} else {
|
||||
error!("No server sender available for PierceFirewall");
|
||||
}
|
||||
|
||||
drop(context);
|
||||
Self::connect_to_peer(peer, client_context, own_username, None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,7 @@ use crate::{
|
||||
actor::{ActorSystem, peer_registry::PeerRegistry},
|
||||
error::{Result, SoulseekRs},
|
||||
message::peer::{FileEntry, SharedDirectory, build_file_search_response},
|
||||
peer::{
|
||||
ConnectionType, DownloadPeer, NewPeer, Peer, PeerMessage,
|
||||
listen::Listen,
|
||||
},
|
||||
peer::{ConnectionType, DownloadPeer, Peer, PeerMessage, listen::Listen},
|
||||
shares::Shares,
|
||||
types::{Download, Search, SearchResult},
|
||||
utils::{lock::RwLockExt, md5},
|
||||
@@ -25,14 +22,11 @@ use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
net::TcpStream,
|
||||
sync::{
|
||||
RwLock,
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicBool, AtomicU32, Ordering},
|
||||
mpsc::{Receiver, Sender},
|
||||
mpsc::{self, Receiver, Sender},
|
||||
},
|
||||
thread::{self, sleep},
|
||||
};
|
||||
use std::{
|
||||
sync::{Arc, mpsc},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use upload_queue::QueuedUpload;
|
||||
@@ -213,11 +207,9 @@ impl Default for ClientSettings {
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum ClientOperation {
|
||||
NewPeer(NewPeer),
|
||||
ConnectToPeer(Peer),
|
||||
SearchResult(SearchResult),
|
||||
PeerDisconnected(u64, String, Option<SoulseekRs>),
|
||||
PierceFireWall(Peer),
|
||||
DownloadFromPeer(u32, Peer, bool),
|
||||
UpdateDownloadTokens(Transfer, String),
|
||||
GetPeerAddressResponse {
|
||||
@@ -298,7 +290,6 @@ pub enum ClientOperation {
|
||||
pub struct ClientContext {
|
||||
pub peer_registry: Option<PeerRegistry>,
|
||||
pub downloads: DownloadStore,
|
||||
sender: Option<Sender<ClientOperation>>,
|
||||
server_sender: Option<Sender<ServerMessage>>,
|
||||
searches: HashMap<String, Search>,
|
||||
private_messages: Vec<UserMessage>,
|
||||
@@ -376,13 +367,6 @@ impl ClientContext {
|
||||
) -> Option<&mut Download> {
|
||||
self.downloads.get_by_token_mut(token)
|
||||
}
|
||||
pub fn get_download_by_file_mut(
|
||||
&mut self,
|
||||
username: &str,
|
||||
filename: &str,
|
||||
) -> Option<&mut Download> {
|
||||
self.downloads.get_by_file_mut(username, filename)
|
||||
}
|
||||
#[must_use]
|
||||
pub fn get_download_tokens(&self) -> Vec<u32> {
|
||||
self.downloads.tokens()
|
||||
@@ -398,13 +382,6 @@ impl ClientContext {
|
||||
) {
|
||||
self.downloads.update_status(token, status);
|
||||
}
|
||||
pub fn remove_queued_download_by_file(
|
||||
&mut self,
|
||||
username: &str,
|
||||
filename: &str,
|
||||
) -> bool {
|
||||
self.downloads.remove_queued_by_file(username, filename)
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientContext {
|
||||
@@ -414,7 +391,6 @@ impl ClientContext {
|
||||
|
||||
Self {
|
||||
peer_registry: None,
|
||||
sender: None,
|
||||
server_sender: None,
|
||||
searches: HashMap::new(),
|
||||
private_messages: Vec::new(),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,37 @@
|
||||
use super::*;
|
||||
|
||||
fn download(
|
||||
username: &str,
|
||||
filename: &str,
|
||||
token: u32,
|
||||
status: DownloadStatus,
|
||||
sender: Sender<DownloadStatus>,
|
||||
) -> Download {
|
||||
Download {
|
||||
username: username.to_string(),
|
||||
filename: filename.to_string(),
|
||||
token,
|
||||
size: 100,
|
||||
download_directory: "test".to_string(),
|
||||
status,
|
||||
sender,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_context_downloads() {
|
||||
let mut context = ClientContext::new();
|
||||
let token = 123;
|
||||
let new_token = 1234;
|
||||
let download = Download {
|
||||
username: "test".to_string(),
|
||||
filename: "test.txt".to_string(),
|
||||
context.add_download(download(
|
||||
"test",
|
||||
"test.txt",
|
||||
token,
|
||||
size: 100,
|
||||
download_directory: "test".to_string(),
|
||||
status: DownloadStatus::Queued,
|
||||
sender: mpsc::channel().0,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
};
|
||||
context.add_download(download);
|
||||
DownloadStatus::Queued,
|
||||
mpsc::channel().0,
|
||||
));
|
||||
assert!(context.get_download_by_token(123).is_some());
|
||||
assert_eq!(context.get_download_tokens(), vec![123]);
|
||||
assert_eq!(context.get_downloads().len(), 1);
|
||||
@@ -35,23 +50,18 @@ fn test_client_context_downloads() {
|
||||
fn test_client_pause_and_resume_download() {
|
||||
let client = Client::new("test-user", "test-password");
|
||||
let (download_sender, download_receiver) = mpsc::channel();
|
||||
let download = Download {
|
||||
username: "peer".to_string(),
|
||||
filename: "song.mp3".to_string(),
|
||||
token: 123,
|
||||
size: 100,
|
||||
download_directory: "test".to_string(),
|
||||
status: DownloadStatus::InProgress {
|
||||
|
||||
client.context.write().unwrap().add_download(download(
|
||||
"peer",
|
||||
"song.mp3",
|
||||
123,
|
||||
DownloadStatus::InProgress {
|
||||
bytes_downloaded: 25,
|
||||
total_bytes: 100,
|
||||
speed_bytes_per_sec: 10.0,
|
||||
},
|
||||
sender: download_sender,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
};
|
||||
|
||||
client.context.write().unwrap().add_download(download);
|
||||
download_sender,
|
||||
));
|
||||
|
||||
assert!(client.pause_download("peer", "song.mp3"));
|
||||
assert!(matches!(
|
||||
@@ -118,17 +128,13 @@ fn fail_queued_downloads_notifies_receiver_and_store() {
|
||||
// must resolve to Failed both on its channel and in the store.
|
||||
let client = Client::new("u", "p");
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
client.context.write().unwrap().add_download(Download {
|
||||
username: "peer".to_string(),
|
||||
filename: "f.mp3".to_string(),
|
||||
token: 7,
|
||||
size: 10,
|
||||
download_directory: "d".to_string(),
|
||||
status: DownloadStatus::Queued,
|
||||
client.context.write().unwrap().add_download(download(
|
||||
"peer",
|
||||
"f.mp3",
|
||||
7,
|
||||
DownloadStatus::Queued,
|
||||
sender,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
});
|
||||
));
|
||||
|
||||
Client::fail_queued_downloads(&client.context, "peer");
|
||||
|
||||
@@ -171,37 +177,26 @@ fn build_search_response_matches_shares_and_echoes_token() {
|
||||
#[test]
|
||||
fn test_client_removes_only_queued_downloads() {
|
||||
let client = Client::new("test-user", "test-password");
|
||||
let queued_download = Download {
|
||||
username: "peer".to_string(),
|
||||
filename: "queued.mp3".to_string(),
|
||||
token: 123,
|
||||
size: 100,
|
||||
download_directory: "test".to_string(),
|
||||
status: DownloadStatus::Queued,
|
||||
sender: mpsc::channel().0,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
};
|
||||
let active_download = Download {
|
||||
username: "peer".to_string(),
|
||||
filename: "active.mp3".to_string(),
|
||||
token: 456,
|
||||
size: 100,
|
||||
download_directory: "test".to_string(),
|
||||
status: DownloadStatus::InProgress {
|
||||
bytes_downloaded: 25,
|
||||
total_bytes: 100,
|
||||
speed_bytes_per_sec: 10.0,
|
||||
},
|
||||
sender: mpsc::channel().0,
|
||||
queue_position: None,
|
||||
metadata: DownloadMetadata::default(),
|
||||
};
|
||||
|
||||
{
|
||||
let mut context = client.context.write().unwrap();
|
||||
context.add_download(queued_download);
|
||||
context.add_download(active_download);
|
||||
context.add_download(download(
|
||||
"peer",
|
||||
"queued.mp3",
|
||||
123,
|
||||
DownloadStatus::Queued,
|
||||
mpsc::channel().0,
|
||||
));
|
||||
context.add_download(download(
|
||||
"peer",
|
||||
"active.mp3",
|
||||
456,
|
||||
DownloadStatus::InProgress {
|
||||
bytes_downloaded: 25,
|
||||
total_bytes: 100,
|
||||
speed_bytes_per_sec: 10.0,
|
||||
},
|
||||
mpsc::channel().0,
|
||||
));
|
||||
}
|
||||
|
||||
assert!(client.remove_queued_download("peer", "queued.mp3"));
|
||||
|
||||
@@ -47,8 +47,6 @@ impl Client {
|
||||
.and_then(|ctx| ctx.own_privileges)
|
||||
}
|
||||
|
||||
/// How many uploads run at once. Lowering it does not interrupt transfers
|
||||
/// already in flight; the queue simply refills more slowly.
|
||||
/// Queued-upload states recorded since the last call, for a caller that
|
||||
/// samples [`Client::uploads`] and would otherwise miss a peer that queued
|
||||
/// and was served between two samples.
|
||||
@@ -60,6 +58,8 @@ impl Client {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// How many uploads run at once. Lowering it does not interrupt transfers
|
||||
/// already in flight; the queue simply refills more slowly.
|
||||
pub fn set_upload_slots(&self, slots: usize) {
|
||||
if let Ok(mut ctx) = self.context.write_safe() {
|
||||
ctx.upload_slots = slots.max(1);
|
||||
|
||||
Reference in New Issue
Block a user