settings dialog works now and reloads the session properly
This commit is contained in:
parent
e4543e1ba2
commit
9cbe16b387
13 changed files with 123 additions and 49 deletions
|
|
@ -107,7 +107,9 @@ mod tests {
|
|||
init_logging();
|
||||
|
||||
let info_hash = Id20::from_str("cab507494d02ebb1178b38f2e9d7be299c86b862").unwrap();
|
||||
let dht = DhtBuilder::new().await.unwrap();
|
||||
let (dht, run_dht) = DhtBuilder::new().await.unwrap();
|
||||
tokio::spawn(run_dht);
|
||||
|
||||
let peer_rx = dht.get_peers(info_hash, None).unwrap();
|
||||
let peer_id = generate_peer_id();
|
||||
match read_metainfo_from_peer_receiver(peer_id, info_hash, Vec::new(), peer_rx, None).await
|
||||
|
|
|
|||
|
|
@ -150,6 +150,23 @@ struct SerializedSessionDatabase {
|
|||
torrents: HashMap<usize, SerializedTorrent>,
|
||||
}
|
||||
|
||||
fn spawn_with_cancel_token(
|
||||
mut cancel_rx: tokio::sync::watch::Receiver<()>,
|
||||
name: &str,
|
||||
span: tracing::Span,
|
||||
fut: impl std::future::Future<Output = anyhow::Result<()>> + Send + 'static,
|
||||
) {
|
||||
spawn(name, span, async move {
|
||||
tokio::select! {
|
||||
r = fut => r,
|
||||
_ = cancel_rx.changed() => {
|
||||
debug!("task canceled");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub struct Session {
|
||||
peer_id: Id20,
|
||||
dht: Option<Dht>,
|
||||
|
|
@ -385,6 +402,8 @@ impl Session {
|
|||
) -> anyhow::Result<Arc<Self>> {
|
||||
let peer_id = opts.peer_id.unwrap_or_else(generate_peer_id);
|
||||
|
||||
let (cancel_tx, cancel_rx) = tokio::sync::watch::channel(());
|
||||
|
||||
let (tcp_listener, tcp_listen_port) = if let Some(port_range) = opts.listen_port_range {
|
||||
let (l, p) = create_tcp_listener(port_range)
|
||||
.await
|
||||
|
|
@ -399,12 +418,26 @@ impl Session {
|
|||
None
|
||||
} else {
|
||||
let dht = if opts.disable_dht_persistence {
|
||||
DhtBuilder::with_config(DhtConfig::default()).await
|
||||
let (dht, run_worker) = DhtBuilder::with_config(DhtConfig::default())
|
||||
.await
|
||||
.context("error initializing DHT")?;
|
||||
spawn_with_cancel_token(cancel_rx.clone(), "dht", error_span!("dht"), run_worker);
|
||||
dht
|
||||
} else {
|
||||
let pdht_config = opts.dht_config.take().unwrap_or_default();
|
||||
PersistentDht::create(Some(pdht_config)).await
|
||||
}
|
||||
.context("error initializing DHT")?;
|
||||
let (dht, run_worker, run_persistence) = PersistentDht::create(Some(pdht_config))
|
||||
.await
|
||||
.context("error initializing persistent DHT")?;
|
||||
spawn_with_cancel_token(cancel_rx.clone(), "dht", error_span!("dht"), run_worker);
|
||||
spawn_with_cancel_token(
|
||||
cancel_rx.clone(),
|
||||
"dht_persistence",
|
||||
error_span!("dht_persistence"),
|
||||
run_persistence,
|
||||
);
|
||||
dht
|
||||
};
|
||||
|
||||
Some(dht)
|
||||
};
|
||||
let peer_opts = opts.peer_opts.unwrap_or_default();
|
||||
|
|
@ -414,8 +447,6 @@ impl Session {
|
|||
};
|
||||
let spawner = BlockingSpawner::default();
|
||||
|
||||
let (cancel_tx, cancel_rx) = tokio::sync::watch::channel(());
|
||||
|
||||
let session = Arc::new(Self {
|
||||
persistence_filename,
|
||||
peer_id,
|
||||
|
|
@ -618,22 +649,26 @@ impl Session {
|
|||
span: tracing::Span,
|
||||
fut: impl std::future::Future<Output = anyhow::Result<()>> + Send + 'static,
|
||||
) {
|
||||
let mut cancel_rx = self.cancel_rx.clone();
|
||||
spawn(name, span, async move {
|
||||
tokio::select! {
|
||||
r = fut => r,
|
||||
_ = cancel_rx.changed() => {
|
||||
debug!("task canceled");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
});
|
||||
spawn_with_cancel_token(self.cancel_rx.clone(), name, span, fut);
|
||||
}
|
||||
|
||||
/// Stop the session and all managed tasks.
|
||||
// TODO: this probably doesn't kill everything properly.
|
||||
pub async fn stop(&self) {
|
||||
let torrents = self
|
||||
.db
|
||||
.read()
|
||||
.torrents
|
||||
.values()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
for torrent in torrents {
|
||||
if let Err(e) = torrent.pause() {
|
||||
debug!("error pausing torrent: {e:#}");
|
||||
}
|
||||
}
|
||||
let _ = self.cancel_tx.send(());
|
||||
// this sucks, but hopefully will be enough
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
|
||||
async fn populate_from_stored(self: &Arc<Self>) -> anyhow::Result<()> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue