Merge pull request #219 from cocool97/improve-storage

feat: add on_piece_completed method on TorrentStorage
This commit is contained in:
Igor Katson 2024-08-28 09:45:25 +01:00 committed by GitHub
commit 92951dcf5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 30 additions and 8 deletions

View file

@ -215,6 +215,8 @@ impl<'a> FileOps<'a> {
format!("error reading {to_read_in_file} bytes, file_id: {file_idx} (\"{name:?}\")") format!("error reading {to_read_in_file} bytes, file_id: {file_idx} (\"{name:?}\")")
})?; })?;
self.files.on_piece_completed(piece_index)?;
piece_remaining_bytes -= to_read_in_file; piece_remaining_bytes -= to_read_in_file;
if piece_remaining_bytes == 0 { if piece_remaining_bytes == 0 {

View file

@ -14,7 +14,10 @@ use librqbit_core::{
}; };
use parking_lot::RwLock; use parking_lot::RwLock;
use peer_binary_protocol::{ use peer_binary_protocol::{
extended::{handshake::{ExtendedHandshake, YourIP}, ExtendedMessage}, extended::{
handshake::{ExtendedHandshake, YourIP},
ExtendedMessage,
},
serialize_piece_preamble, Handshake, Message, MessageOwned, PIECE_MESSAGE_DEFAULT_LEN, serialize_piece_preamble, Handshake, Message, MessageOwned, PIECE_MESSAGE_DEFAULT_LEN,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View file

@ -27,7 +27,7 @@ impl StorageFactory for InMemoryExampleStorageFactory {
fn create( fn create(
&self, &self,
info: &crate::torrent_state::ManagedTorrentInfo, info: &crate::torrent_state::ManagedTorrentShared,
) -> anyhow::Result<InMemoryExampleStorage> { ) -> anyhow::Result<InMemoryExampleStorage> {
InMemoryExampleStorage::new(info.lengths, info.file_infos.clone()) InMemoryExampleStorage::new(info.lengths, info.file_infos.clone())
} }
@ -111,7 +111,7 @@ impl TorrentStorage for InMemoryExampleStorage {
})) }))
} }
fn init(&mut self, _meta: &crate::ManagedTorrentInfo) -> anyhow::Result<()> { fn init(&mut self, _meta: &crate::ManagedTorrentShared) -> anyhow::Result<()> {
Ok(()) Ok(())
} }

View file

@ -4,7 +4,7 @@ use parking_lot::RwLock;
use crate::{ use crate::{
storage::{StorageFactory, StorageFactoryExt, TorrentStorage}, storage::{StorageFactory, StorageFactoryExt, TorrentStorage},
FileInfos, ManagedTorrentInfo, FileInfos, ManagedTorrentShared,
}; };
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -18,7 +18,7 @@ pub struct MmapStorage {
impl StorageFactory for MmapStorageFactory { impl StorageFactory for MmapStorageFactory {
type Storage = MmapStorage; type Storage = MmapStorage;
fn create(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Self::Storage> { fn create(&self, info: &ManagedTorrentShared) -> anyhow::Result<Self::Storage> {
Ok(MmapStorage { Ok(MmapStorage {
mmap: RwLock::new( mmap: RwLock::new(
MmapOptions::new() MmapOptions::new()
@ -63,11 +63,15 @@ impl TorrentStorage for MmapStorage {
anyhow::bail!("not implemented") anyhow::bail!("not implemented")
} }
fn init(&mut self, _meta: &ManagedTorrentInfo) -> anyhow::Result<()> { fn init(&mut self, _meta: &ManagedTorrentShared) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
fn remove_directory_if_empty(&self, _path: &std::path::Path) -> anyhow::Result<()> { fn remove_directory_if_empty(&self, _path: &std::path::Path) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
fn on_piece_completed(&self, _file_id: usize, _offset: u64) -> anyhow::Result<()> {
Ok(())
}
} }

View file

@ -11,6 +11,8 @@ use std::{
path::Path, path::Path,
}; };
use librqbit_core::lengths::ValidPieceIndex;
use crate::torrent_state::ManagedTorrentShared; use crate::torrent_state::ManagedTorrentShared;
pub trait StorageFactory: Send + Sync + Any { pub trait StorageFactory: Send + Sync + Any {
@ -97,6 +99,12 @@ pub trait TorrentStorage: Send + Sync {
/// Replace the current storage with a dummy, and return a new one that should be used instead. /// Replace the current storage with a dummy, and return a new one that should be used instead.
/// This is used to make the underlying object useless when e.g. pausing the torrent. /// This is used to make the underlying object useless when e.g. pausing the torrent.
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>>; fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>>;
/// Callback called every time a piece has completed and has been validated.
/// Default implementation does nothing, but can be override in trait implementations.
fn on_piece_completed(&self, _piece_index: ValidPieceIndex) -> anyhow::Result<()> {
Ok(())
}
} }
impl<U: TorrentStorage + ?Sized> TorrentStorage for Box<U> { impl<U: TorrentStorage + ?Sized> TorrentStorage for Box<U> {
@ -127,4 +135,8 @@ impl<U: TorrentStorage + ?Sized> TorrentStorage for Box<U> {
fn init(&mut self, meta: &ManagedTorrentShared) -> anyhow::Result<()> { fn init(&mut self, meta: &ManagedTorrentShared) -> anyhow::Result<()> {
(**self).init(meta) (**self).init(meta)
} }
fn on_piece_completed(&self, piece_id: ValidPieceIndex) -> anyhow::Result<()> {
(**self).on_piece_completed(piece_id)
}
} }

View file

@ -5,7 +5,7 @@ use std::{
time::Duration, time::Duration,
}; };
use anyhow::{bail, Context}; use anyhow::bail;
use librqbit_core::Id20; use librqbit_core::Id20;
use parking_lot::RwLock; use parking_lot::RwLock;
use rand::{thread_rng, Rng, RngCore, SeedableRng}; use rand::{thread_rng, Rng, RngCore, SeedableRng};
@ -97,6 +97,7 @@ impl TestPeerMetadata {
#[cfg(feature = "http-api")] #[cfg(feature = "http-api")]
async fn debug_server() -> anyhow::Result<()> { async fn debug_server() -> anyhow::Result<()> {
use anyhow::Context;
use axum::{response::IntoResponse, routing::get, Router}; use axum::{response::IntoResponse, routing::get, Router};
async fn backtraces() -> impl IntoResponse { async fn backtraces() -> impl IntoResponse {
#[cfg(feature = "async-bt")] #[cfg(feature = "async-bt")]

View file

@ -99,7 +99,7 @@ impl Serialize for YourIP {
IpAddr::V6(ipv6) => { IpAddr::V6(ipv6) => {
let buf = ipv6.octets(); let buf = ipv6.octets();
serializer.serialize_bytes(&buf) serializer.serialize_bytes(&buf)
}, }
} }
} }
} }