Clone storage factories...
This commit is contained in:
parent
07a5b69a25
commit
427f490a61
10 changed files with 62 additions and 21 deletions
|
|
@ -16,10 +16,7 @@ use crate::{
|
||||||
peer_connection::PeerConnectionOptions,
|
peer_connection::PeerConnectionOptions,
|
||||||
read_buf::ReadBuf,
|
read_buf::ReadBuf,
|
||||||
spawn_utils::BlockingSpawner,
|
spawn_utils::BlockingSpawner,
|
||||||
storage::{
|
storage::{filesystem::FilesystemStorageFactory, BoxStorageFactory, StorageFactoryExt},
|
||||||
filesystem::{FilesystemStorageFactory, MmapFilesystemStorageFactory},
|
|
||||||
BoxStorageFactory, StorageFactoryExt,
|
|
||||||
},
|
|
||||||
torrent_state::{
|
torrent_state::{
|
||||||
ManagedTorrentBuilder, ManagedTorrentHandle, ManagedTorrentState, TorrentStateLive,
|
ManagedTorrentBuilder, ManagedTorrentHandle, ManagedTorrentState, TorrentStateLive,
|
||||||
},
|
},
|
||||||
|
|
@ -193,7 +190,7 @@ pub struct Session {
|
||||||
|
|
||||||
default_defer_writes: bool,
|
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.
|
// This is stored for all tasks to stop when session is dropped.
|
||||||
_cancellation_token_drop_guard: DropGuard,
|
_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.
|
// If true, will write to disk in separate threads. The downside is additional allocations.
|
||||||
// May be useful if the disk is slow.
|
// May be useful if the disk is slow.
|
||||||
pub default_defer_writes: bool,
|
pub default_defer_writes: bool,
|
||||||
// pub default_storage_factory: Option<BoxStorageFactory>,
|
|
||||||
|
pub default_storage_factory: Option<BoxStorageFactory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tcp_listener(
|
async fn create_tcp_listener(
|
||||||
|
|
@ -530,6 +528,7 @@ impl Session {
|
||||||
cancellation_token: token,
|
cancellation_token: token,
|
||||||
tcp_listen_port,
|
tcp_listen_port,
|
||||||
default_defer_writes: opts.default_defer_writes,
|
default_defer_writes: opts.default_defer_writes,
|
||||||
|
default_storage_factory: opts.default_storage_factory,
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(tcp_listener) = tcp_listener {
|
if let Some(tcp_listener) = tcp_listener {
|
||||||
|
|
@ -1023,9 +1022,8 @@ impl Session {
|
||||||
let storage_factory = opts
|
let storage_factory = opts
|
||||||
.storage_factory
|
.storage_factory
|
||||||
.take()
|
.take()
|
||||||
// .unwrap_or_else(|| self.default_storage_factory.clone())
|
.or_else(|| self.default_storage_factory.as_ref().map(|f| f.clone_box()))
|
||||||
// .unwrap_or_else(|| FilesystemStorageFactory::default().boxed());
|
.unwrap_or_else(|| FilesystemStorageFactory::default().boxed());
|
||||||
.unwrap_or_else(|| MmapFilesystemStorageFactory::default().boxed());
|
|
||||||
|
|
||||||
if opts.list_only {
|
if opts.list_only {
|
||||||
return Ok(AddTorrentResponse::ListOnly(ListOnlyResponse {
|
return Ok(AddTorrentResponse::ListOnly(ListOnlyResponse {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::type_aliases::FileInfos;
|
use crate::type_aliases::FileInfos;
|
||||||
|
|
||||||
use crate::storage::{StorageFactory, TorrentStorage};
|
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
||||||
|
|
||||||
struct InMemoryPiece {
|
struct InMemoryPiece {
|
||||||
bytes: Box<[u8]>,
|
bytes: Box<[u8]>,
|
||||||
|
|
@ -19,7 +19,7 @@ impl InMemoryPiece {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub struct InMemoryExampleStorageFactory {}
|
pub struct InMemoryExampleStorageFactory {}
|
||||||
|
|
||||||
impl StorageFactory for InMemoryExampleStorageFactory {
|
impl StorageFactory for InMemoryExampleStorageFactory {
|
||||||
|
|
@ -31,6 +31,10 @@ impl StorageFactory for InMemoryExampleStorageFactory {
|
||||||
) -> anyhow::Result<InMemoryExampleStorage> {
|
) -> anyhow::Result<InMemoryExampleStorage> {
|
||||||
InMemoryExampleStorage::new(info.lengths, info.file_infos.clone())
|
InMemoryExampleStorage::new(info.lengths, info.file_infos.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.clone().boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InMemoryExampleStorage {
|
pub struct InMemoryExampleStorage {
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ use memmap2::{MmapMut, MmapOptions};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
storage::{StorageFactory, TorrentStorage},
|
storage::{StorageFactory, StorageFactoryExt, TorrentStorage},
|
||||||
FileInfos, ManagedTorrentInfo,
|
FileInfos, ManagedTorrentInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub struct MmapStorageFactory {}
|
pub struct MmapStorageFactory {}
|
||||||
|
|
||||||
pub struct MmapStorage {
|
pub struct MmapStorage {
|
||||||
|
|
@ -28,6 +28,10 @@ impl StorageFactory for MmapStorageFactory {
|
||||||
file_infos: info.file_infos.clone(),
|
file_infos: info.file_infos.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.clone().boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TorrentStorage for MmapStorage {
|
impl TorrentStorage for MmapStorage {
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ use std::{
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
||||||
use crate::torrent_state::ManagedTorrentInfo;
|
use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo};
|
||||||
|
|
||||||
use crate::storage::{StorageFactory, TorrentStorage};
|
use crate::storage::{StorageFactory, TorrentStorage};
|
||||||
|
|
||||||
use super::opened_file::OpenedFile;
|
use super::opened_file::OpenedFile;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub struct FilesystemStorageFactory {}
|
pub struct FilesystemStorageFactory {}
|
||||||
|
|
||||||
impl StorageFactory for FilesystemStorageFactory {
|
impl StorageFactory for FilesystemStorageFactory {
|
||||||
|
|
@ -59,6 +59,10 @@ impl StorageFactory for FilesystemStorageFactory {
|
||||||
opened_files: files,
|
opened_files: files,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilesystemStorage {
|
pub struct FilesystemStorage {
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ use parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::torrent_state::ManagedTorrentInfo;
|
use crate::torrent_state::ManagedTorrentInfo;
|
||||||
|
|
||||||
use crate::storage::{StorageFactory, TorrentStorage};
|
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
||||||
|
|
||||||
use super::{FilesystemStorage, FilesystemStorageFactory};
|
use super::{FilesystemStorage, FilesystemStorageFactory};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub struct MmapFilesystemStorageFactory {}
|
pub struct MmapFilesystemStorageFactory {}
|
||||||
|
|
||||||
type OpenedMmap = RwLock<MmapMut>;
|
type OpenedMmap = RwLock<MmapMut>;
|
||||||
|
|
@ -36,6 +36,10 @@ impl StorageFactory for MmapFilesystemStorageFactory {
|
||||||
fs: fs_storage,
|
fs: fs_storage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MmapFilesystemStorage {
|
pub struct MmapFilesystemStorage {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@ use std::time::Duration;
|
||||||
|
|
||||||
use rand_distr::Distribution;
|
use rand_distr::Distribution;
|
||||||
|
|
||||||
use crate::storage::{StorageFactory, TorrentStorage};
|
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct SlowStorageFactory<U> {
|
pub struct SlowStorageFactory<U> {
|
||||||
underlying_factory: 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>;
|
type Storage = SlowStorage<U::Storage>;
|
||||||
|
|
||||||
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::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 {
|
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
|
||||||
self.underlying_factory.is_type_id(type_id)
|
self.underlying_factory.is_type_id(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.clone().boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SlowStorage<U> {
|
pub struct SlowStorage<U> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::storage::{StorageFactory, TorrentStorage};
|
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct TimingStorageFactory<U> {
|
pub struct TimingStorageFactory<U> {
|
||||||
name: String,
|
name: String,
|
||||||
underlying_factory: U,
|
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>;
|
type Storage = TimingStorage<U::Storage>;
|
||||||
|
|
||||||
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::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 {
|
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
|
||||||
self.underlying_factory.is_type_id(type_id)
|
self.underlying_factory.is_type_id(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> crate::storage::BoxStorageFactory {
|
||||||
|
self.clone().boxed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TimingStorage<U> {
|
pub struct TimingStorage<U> {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ pub trait StorageFactory: Send + Sync + Any {
|
||||||
fn is_type_id(&self, type_id: TypeId) -> bool {
|
fn is_type_id(&self, type_id: TypeId) -> bool {
|
||||||
Self::type_id(self) == type_id
|
Self::type_id(self) == type_id
|
||||||
}
|
}
|
||||||
|
fn clone_box(&self) -> BoxStorageFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BoxStorageFactory = Box<dyn StorageFactory<Storage = Box<dyn TorrentStorage>>>;
|
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 {
|
fn is_type_id(&self, type_id: TypeId) -> bool {
|
||||||
self.sf.type_id() == type_id
|
self.sf.type_id() == type_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> BoxStorageFactory {
|
||||||
|
self.sf.clone_box()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box::new(Wrapper { sf: self })
|
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> {
|
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<U::Storage> {
|
||||||
(**self).init_storage(info)
|
(**self).init_storage(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> BoxStorageFactory {
|
||||||
|
(**self).clone_box()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TorrentStorage: Send + Sync {
|
pub trait TorrentStorage: Send + Sync {
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ async fn test_e2e() {
|
||||||
listen_port_range: Some(15100..17000),
|
listen_port_range: Some(15100..17000),
|
||||||
enable_upnp_port_forwarding: false,
|
enable_upnp_port_forwarding: false,
|
||||||
default_defer_writes: false,
|
default_defer_writes: false,
|
||||||
|
default_storage_factory: None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,13 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
|
||||||
},
|
},
|
||||||
enable_upnp_port_forwarding: !opts.disable_upnp,
|
enable_upnp_port_forwarding: !opts.disable_upnp,
|
||||||
default_defer_writes: opts.defer_writes,
|
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 {
|
let stats_printer = |session: Arc<Session>| async move {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue