Make all experimental storages optional
This commit is contained in:
parent
0a1d389bc7
commit
0b1499aa10
7 changed files with 81 additions and 14 deletions
|
|
@ -70,9 +70,10 @@ tokio-util = "0.7.10"
|
||||||
bytes = "1.5.0"
|
bytes = "1.5.0"
|
||||||
rlimit = "0.10.1"
|
rlimit = "0.10.1"
|
||||||
async-stream = "0.3.5"
|
async-stream = "0.3.5"
|
||||||
memmap2 = "0.9.4"
|
memmap2 = { version = "0.9.4" }
|
||||||
rand_distr = "0.4.3"
|
|
||||||
lru = "0.12.3"
|
rand_distr = { version = "0.4.3", optional = true }
|
||||||
|
lru = { version = "0.12.3", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures = { version = "0.3" }
|
futures = { version = "0.3" }
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,55 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use librqbit::{
|
use librqbit::{
|
||||||
storage::{examples::mmap::MmapStorageFactory, StorageFactoryExt},
|
storage::{StorageFactory, StorageFactoryExt, TorrentStorage},
|
||||||
SessionOptions,
|
SessionOptions,
|
||||||
};
|
};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy)]
|
||||||
|
struct CustomStorageFactory {
|
||||||
|
_some_state_used_to_create_per_torrent_storage: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy)]
|
||||||
|
struct CustomStorage {
|
||||||
|
_some_state_for_per_torrent_storage: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StorageFactory for CustomStorageFactory {
|
||||||
|
type Storage = CustomStorage;
|
||||||
|
|
||||||
|
fn init_storage(&self, _info: &librqbit::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
|
||||||
|
Ok(CustomStorage::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> librqbit::storage::BoxStorageFactory {
|
||||||
|
self.boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TorrentStorage for CustomStorage {
|
||||||
|
fn pread_exact(&self, _file_id: usize, _offset: u64, _buf: &mut [u8]) -> anyhow::Result<()> {
|
||||||
|
anyhow::bail!("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pwrite_all(&self, _file_id: usize, _offset: u64, _buf: &[u8]) -> anyhow::Result<()> {
|
||||||
|
anyhow::bail!("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file(&self, _file_id: usize, _filename: &std::path::Path) -> anyhow::Result<()> {
|
||||||
|
anyhow::bail!("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_file_length(&self, _file_id: usize, _length: u64) -> anyhow::Result<()> {
|
||||||
|
anyhow::bail!("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {
|
||||||
|
anyhow::bail!("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
// Output logs to console.
|
// Output logs to console.
|
||||||
|
|
@ -31,7 +75,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
include_bytes!("../resources/ubuntu-21.04-live-server-amd64.iso.torrent").into(),
|
include_bytes!("../resources/ubuntu-21.04-live-server-amd64.iso.torrent").into(),
|
||||||
),
|
),
|
||||||
Some(librqbit::AddTorrentOptions {
|
Some(librqbit::AddTorrentOptions {
|
||||||
storage_factory: Some(MmapStorageFactory::default().boxed()),
|
storage_factory: Some(CustomStorageFactory::default().boxed()),
|
||||||
paused: false,
|
paused: false,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
/*
|
||||||
|
A storage middleware that slows down the underlying storage.
|
||||||
|
*/
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use rand_distr::Distribution;
|
use rand_distr::Distribution;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
/*
|
||||||
|
A storage middleware that logs the time underlying storage operations took.
|
||||||
|
*/
|
||||||
|
|
||||||
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
/*
|
||||||
|
A storage middleware that caches pieces in memory, so that subsequent reads (for checksumming) are
|
||||||
|
free.
|
||||||
|
|
||||||
|
An example, untested and unproven to be useful.
|
||||||
|
*/
|
||||||
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
pub mod examples;
|
|
||||||
pub mod filesystem;
|
pub mod filesystem;
|
||||||
|
|
||||||
|
#[cfg(feature = "storage_examples")]
|
||||||
|
pub mod examples;
|
||||||
|
|
||||||
|
#[cfg(feature = "storage_middleware")]
|
||||||
pub mod middleware;
|
pub mod middleware;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -65,14 +69,22 @@ impl<U: StorageFactory + ?Sized> StorageFactory for Box<U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TorrentStorage: Send + Sync {
|
pub trait TorrentStorage: Send + Sync {
|
||||||
|
/// Given a file_id (which you can get more info from in init_storage() through torrent info)
|
||||||
|
/// read buf.len() bytes into buf at offset.
|
||||||
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()>;
|
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()>;
|
||||||
|
|
||||||
|
/// Given a file_id (which you can get more info from in init_storage() through torrent info)
|
||||||
|
/// write buf.len() bytes into the file at offset.
|
||||||
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()>;
|
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()>;
|
||||||
|
|
||||||
|
/// Remove a file from the storage. If not supported, or it doesn't matter, just return Ok(())
|
||||||
fn remove_file(&self, file_id: usize, filename: &Path) -> anyhow::Result<()>;
|
fn remove_file(&self, file_id: usize, filename: &Path) -> anyhow::Result<()>;
|
||||||
|
|
||||||
|
/// E.g. for filesystem backend ensure that the file has a certain length, and grow/shrink as needed.
|
||||||
fn ensure_file_length(&self, file_id: usize, length: u64) -> anyhow::Result<()>;
|
fn ensure_file_length(&self, file_id: usize, length: u64) -> anyhow::Result<()>;
|
||||||
|
|
||||||
|
/// 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.
|
||||||
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>>;
|
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,7 @@ use anyhow::Context;
|
||||||
use tokio::{io::AsyncReadExt, time::timeout};
|
use tokio::{io::AsyncReadExt, time::timeout};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{create_torrent, AddTorrent, CreateTorrentOptions, Session};
|
||||||
create_torrent,
|
|
||||||
storage::{examples::inmemory::InMemoryExampleStorageFactory, StorageFactoryExt},
|
|
||||||
AddTorrent, CreateTorrentOptions, Session,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::test_util::create_default_random_dir_with_torrents;
|
use super::test_util::create_default_random_dir_with_torrents;
|
||||||
|
|
||||||
|
|
@ -86,7 +82,6 @@ async fn e2e_stream() -> anyhow::Result<()> {
|
||||||
AddTorrent::from_bytes(torrent.as_bytes()?),
|
AddTorrent::from_bytes(torrent.as_bytes()?),
|
||||||
Some(crate::AddTorrentOptions {
|
Some(crate::AddTorrentOptions {
|
||||||
paused: false,
|
paused: false,
|
||||||
storage_factory: Some(InMemoryExampleStorageFactory::default().boxed()),
|
|
||||||
initial_peers: Some(vec![peer]),
|
initial_peers: Some(vec![peer]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue