Clone storage factories...

This commit is contained in:
Igor Katson 2024-05-02 20:16:14 +01:00
parent 07a5b69a25
commit 427f490a61
10 changed files with 62 additions and 21 deletions

View file

@ -16,10 +16,7 @@ use crate::{
peer_connection::PeerConnectionOptions,
read_buf::ReadBuf,
spawn_utils::BlockingSpawner,
storage::{
filesystem::{FilesystemStorageFactory, MmapFilesystemStorageFactory},
BoxStorageFactory, StorageFactoryExt,
},
storage::{filesystem::FilesystemStorageFactory, BoxStorageFactory, StorageFactoryExt},
torrent_state::{
ManagedTorrentBuilder, ManagedTorrentHandle, ManagedTorrentState, TorrentStateLive,
},
@ -193,7 +190,7 @@ pub struct Session {
default_defer_writes: bool,
// default_storage_factory: Option<BoxStorageFactory>,
default_storage_factory: Option<BoxStorageFactory>,
// This is stored for all tasks to stop when session is dropped.
_cancellation_token_drop_guard: DropGuard,
@ -430,7 +427,8 @@ pub struct SessionOptions {
// If true, will write to disk in separate threads. The downside is additional allocations.
// May be useful if the disk is slow.
pub default_defer_writes: bool,
// pub default_storage_factory: Option<BoxStorageFactory>,
pub default_storage_factory: Option<BoxStorageFactory>,
}
async fn create_tcp_listener(
@ -530,6 +528,7 @@ impl Session {
cancellation_token: token,
tcp_listen_port,
default_defer_writes: opts.default_defer_writes,
default_storage_factory: opts.default_storage_factory,
});
if let Some(tcp_listener) = tcp_listener {
@ -1023,9 +1022,8 @@ impl Session {
let storage_factory = opts
.storage_factory
.take()
// .unwrap_or_else(|| self.default_storage_factory.clone())
// .unwrap_or_else(|| FilesystemStorageFactory::default().boxed());
.unwrap_or_else(|| MmapFilesystemStorageFactory::default().boxed());
.or_else(|| self.default_storage_factory.as_ref().map(|f| f.clone_box()))
.unwrap_or_else(|| FilesystemStorageFactory::default().boxed());
if opts.list_only {
return Ok(AddTorrentResponse::ListOnly(ListOnlyResponse {

View file

@ -6,7 +6,7 @@ use parking_lot::RwLock;
use crate::type_aliases::FileInfos;
use crate::storage::{StorageFactory, TorrentStorage};
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
struct InMemoryPiece {
bytes: Box<[u8]>,
@ -19,7 +19,7 @@ impl InMemoryPiece {
}
}
#[derive(Default)]
#[derive(Default, Clone)]
pub struct InMemoryExampleStorageFactory {}
impl StorageFactory for InMemoryExampleStorageFactory {
@ -31,6 +31,10 @@ impl StorageFactory for InMemoryExampleStorageFactory {
) -> anyhow::Result<InMemoryExampleStorage> {
InMemoryExampleStorage::new(info.lengths, info.file_infos.clone())
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.clone().boxed()
}
}
pub struct InMemoryExampleStorage {

View file

@ -3,11 +3,11 @@ use memmap2::{MmapMut, MmapOptions};
use parking_lot::RwLock;
use crate::{
storage::{StorageFactory, TorrentStorage},
storage::{StorageFactory, StorageFactoryExt, TorrentStorage},
FileInfos, ManagedTorrentInfo,
};
#[derive(Default)]
#[derive(Default, Clone)]
pub struct MmapStorageFactory {}
pub struct MmapStorage {
@ -28,6 +28,10 @@ impl StorageFactory for MmapStorageFactory {
file_infos: info.file_infos.clone(),
})
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.clone().boxed()
}
}
impl TorrentStorage for MmapStorage {

View file

@ -6,13 +6,13 @@ use std::{
use anyhow::Context;
use crate::torrent_state::ManagedTorrentInfo;
use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo};
use crate::storage::{StorageFactory, TorrentStorage};
use super::opened_file::OpenedFile;
#[derive(Default)]
#[derive(Default, Clone, Copy)]
pub struct FilesystemStorageFactory {}
impl StorageFactory for FilesystemStorageFactory {
@ -59,6 +59,10 @@ impl StorageFactory for FilesystemStorageFactory {
opened_files: files,
})
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.boxed()
}
}
pub struct FilesystemStorage {

View file

@ -6,11 +6,11 @@ use parking_lot::RwLock;
use crate::torrent_state::ManagedTorrentInfo;
use crate::storage::{StorageFactory, TorrentStorage};
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
use super::{FilesystemStorage, FilesystemStorageFactory};
#[derive(Default)]
#[derive(Default, Clone, Copy)]
pub struct MmapFilesystemStorageFactory {}
type OpenedMmap = RwLock<MmapMut>;
@ -36,6 +36,10 @@ impl StorageFactory for MmapFilesystemStorageFactory {
fs: fs_storage,
})
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.boxed()
}
}
pub struct MmapFilesystemStorage {

View file

@ -2,8 +2,9 @@ use std::time::Duration;
use rand_distr::Distribution;
use crate::storage::{StorageFactory, TorrentStorage};
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
#[derive(Clone)]
pub struct SlowStorageFactory<U> {
underlying_factory: U,
}
@ -16,7 +17,7 @@ impl<U: StorageFactory> SlowStorageFactory<U> {
}
}
impl<U: StorageFactory> StorageFactory for SlowStorageFactory<U> {
impl<U: StorageFactory + Clone> StorageFactory for SlowStorageFactory<U> {
type Storage = SlowStorage<U::Storage>;
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
@ -28,6 +29,10 @@ impl<U: StorageFactory> StorageFactory for SlowStorageFactory<U> {
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
self.underlying_factory.is_type_id(type_id)
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.clone().boxed()
}
}
pub struct SlowStorage<U> {

View file

@ -1,5 +1,6 @@
use crate::storage::{StorageFactory, TorrentStorage};
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
#[derive(Clone)]
pub struct TimingStorageFactory<U> {
name: String,
underlying_factory: U,
@ -14,7 +15,7 @@ impl<U> TimingStorageFactory<U> {
}
}
impl<U: StorageFactory> StorageFactory for TimingStorageFactory<U> {
impl<U: StorageFactory + Clone> StorageFactory for TimingStorageFactory<U> {
type Storage = TimingStorage<U::Storage>;
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
@ -27,6 +28,10 @@ impl<U: StorageFactory> StorageFactory for TimingStorageFactory<U> {
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
self.underlying_factory.is_type_id(type_id)
}
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
self.clone().boxed()
}
}
pub struct TimingStorage<U> {

View file

@ -16,6 +16,7 @@ pub trait StorageFactory: Send + Sync + Any {
fn is_type_id(&self, type_id: TypeId) -> bool {
Self::type_id(self) == type_id
}
fn clone_box(&self) -> BoxStorageFactory;
}
pub type BoxStorageFactory = Box<dyn StorageFactory<Storage = Box<dyn TorrentStorage>>>;
@ -41,6 +42,10 @@ impl<SF: StorageFactory> StorageFactoryExt for SF {
fn is_type_id(&self, type_id: TypeId) -> bool {
self.sf.type_id() == type_id
}
fn clone_box(&self) -> BoxStorageFactory {
self.sf.clone_box()
}
}
Box::new(Wrapper { sf: self })
@ -53,6 +58,10 @@ impl<U: StorageFactory + ?Sized> StorageFactory for Box<U> {
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<U::Storage> {
(**self).init_storage(info)
}
fn clone_box(&self) -> BoxStorageFactory {
(**self).clone_box()
}
}
pub trait TorrentStorage: Send + Sync {

View file

@ -73,6 +73,7 @@ async fn test_e2e() {
listen_port_range: Some(15100..17000),
enable_upnp_port_forwarding: false,
default_defer_writes: false,
default_storage_factory: None,
},
)
.await

View file

@ -297,6 +297,13 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
},
enable_upnp_port_forwarding: !opts.disable_upnp,
default_defer_writes: opts.defer_writes,
default_storage_factory: Some({
if opts.experimental_mmap_storage {
MmapFilesystemStorageFactory::default().boxed()
} else {
FilesystemStorageFactory::default().boxed()
}
}),
};
let stats_printer = |session: Arc<Session>| async move {