aria2_core/engine/
bt_download_seeding.rs1use tracing::info;
2
3use crate::engine::bt_download_command::BtDownloadCommand;
4use crate::engine::bt_peer_connection::BtPeerConn;
5use crate::engine::bt_piece_downloader::FileBackedPieceProvider;
6use crate::engine::bt_seed_manager::{BtSeedManager, SeedExitCondition};
7use crate::engine::bt_upload_session::BtSeedingConfig;
8use crate::error::Result;
9
10impl BtDownloadCommand {
11 pub async fn run_seeding_phase(
12 &mut self,
13 connections: Vec<BtPeerConn>,
14 piece_length: u32,
15 num_pieces: u32,
16 ) -> Result<()> {
17 if connections.is_empty() {
18 info!("No active peers for seeding");
19 return Ok(());
20 }
21
22 let file_provider = std::sync::Arc::new(FileBackedPieceProvider::new(
23 self.output_path.clone(),
24 piece_length,
25 num_pieces,
26 self.multi_file_layout.clone(),
27 ));
28
29 let upload_limit = { self.group.read().await.options().max_upload_limit };
30 let config = BtSeedingConfig {
31 max_upload_bytes_per_sec: upload_limit,
32 max_peers_to_unchoke: 4,
33 optimistic_unchoke_interval_secs: 30,
34 };
35
36 let exit_cond = match (self.seed_time, self.seed_ratio) {
37 (Some(t), Some(r)) => SeedExitCondition {
38 seed_time: Some(t),
39 seed_ratio: Some(r),
40 },
41 (Some(t), None) => SeedExitCondition {
42 seed_time: Some(t),
43 seed_ratio: None,
44 },
45 (None, Some(r)) => SeedExitCondition {
46 seed_time: None,
47 seed_ratio: Some(r),
48 },
49 (None, None) => SeedExitCondition::infinite(),
50 };
51
52 let plain_connections: Vec<aria2_protocol::bittorrent::peer::connection::PeerConnection> =
53 connections
54 .into_iter()
55 .filter_map(|c| match c.inner {
56 crate::engine::bt_peer_connection::InnerConnection::Plain(p) => Some(p),
57 _ => None,
58 })
59 .collect();
60
61 let mut manager = BtSeedManager::new_with_choking_algo(
62 plain_connections,
63 file_provider,
64 config,
65 exit_cond,
66 self.completed_bytes,
67 self.choking_algo.take(),
68 );
69 manager.run_seeding_loop().await?;
70
71 self.total_uploaded = manager.total_uploaded();
72 info!(
73 "Seeding complete: uploaded {} bytes in {:?}",
74 self.total_uploaded,
75 manager.seeding_duration()
76 );
77 Ok(())
78 }
79}