Skip to content

Commit

Permalink
remove dependant on nightly Rust feature (#1198)
Browse files Browse the repository at this point in the history
* remove dependant on nightly Rust feature

* do not box spawn blocking future
  • Loading branch information
fakeshadow authored Feb 4, 2025
1 parent 4d339df commit 7645226
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 22 deletions.
1 change: 1 addition & 0 deletions http-file/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# unreleased 0.2.0
## Change
- project compile on stable Rust channel with MSRV of 1.79
- update `tokio-uring` to `0.5.0`
2 changes: 0 additions & 2 deletions http-file/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! local file serving with http.
#![feature(impl_trait_in_assoc_type)]

pub mod runtime;

mod buf;
Expand Down
62 changes: 43 additions & 19 deletions http-file/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,42 @@ pub(crate) use tokio_impl::TokioFs;

#[cfg(feature = "tokio")]
mod tokio_impl {
use core::{
pin::Pin,
task::{Context, Poll},
};

use tokio::{
fs::File,
io::{AsyncReadExt, AsyncSeekExt},
};

use super::*;

type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

pub struct OpenFuture<F> {
handle: tokio::task::JoinHandle<F>,
}

impl<F> Future for OpenFuture<F> {
type Output = F;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.get_mut().handle).poll(cx).map(|res| res.unwrap())
}
}

#[derive(Clone)]
pub struct TokioFs;

impl AsyncFs for TokioFs {
type File = TokioFile;
type OpenFuture = impl Future<Output = io::Result<Self::File>> + Send;
type OpenFuture = OpenFuture<io::Result<Self::File>>;

fn open(&self, path: PathBuf) -> Self::OpenFuture {
async {
tokio::task::spawn_blocking(move || {
OpenFuture {
handle: tokio::task::spawn_blocking(move || {
let file = std::fs::File::open(path)?;
let meta = file.metadata()?;
let modified_time = meta.modified().ok();
Expand All @@ -84,9 +103,7 @@ mod tokio_impl {
modified_time,
len,
})
})
.await
.unwrap()
}),
}
}
}
Expand All @@ -109,25 +126,25 @@ mod tokio_impl {

impl ChunkRead for TokioFile {
type SeekFuture<'f>
= impl Future<Output = io::Result<()>> + Send + 'f
= BoxFuture<'f, io::Result<()>>
where
Self: 'f;

type Future = impl Future<Output = io::Result<Option<(Self, BytesMut, usize)>>> + Send;
type Future = BoxFuture<'static, io::Result<Option<(Self, BytesMut, usize)>>>;

fn seek(&mut self, pos: SeekFrom) -> Self::SeekFuture<'_> {
async move { self.file.seek(pos).await.map(|_| ()) }
Box::pin(async move { self.file.seek(pos).await.map(|_| ()) })
}

fn next(mut self, mut buf: BytesMut) -> Self::Future {
async {
Box::pin(async {
let n = self.file.read_buf(&mut buf).await?;
if n == 0 {
Ok(None)
} else {
Ok(Some((self, buf, n)))
}
}
})
}
}
}
Expand All @@ -137,19 +154,26 @@ pub(crate) use tokio_uring_impl::TokioUringFs;

#[cfg(feature = "tokio-uring")]
mod tokio_uring_impl {
use core::{
future::{ready, Ready},
pin::Pin,
};

use tokio_uring::fs::File;

use super::*;

type BoxFuture<'f, T> = Pin<Box<dyn Future<Output = T> + 'f>>;

#[derive(Clone)]
pub struct TokioUringFs;

impl AsyncFs for TokioUringFs {
type File = TokioUringFile;
type OpenFuture = impl Future<Output = io::Result<Self::File>>;
type OpenFuture = BoxFuture<'static, io::Result<Self::File>>;

fn open(&self, path: PathBuf) -> Self::OpenFuture {
async {
Box::pin(async {
let file = File::open(path).await?;

// SAFETY: fd is borrowed and lives longer than the unsafe block
Expand All @@ -173,7 +197,7 @@ mod tokio_uring_impl {
modified_time,
len,
})
}
})
}
}

Expand All @@ -196,22 +220,22 @@ mod tokio_uring_impl {

impl ChunkRead for TokioUringFile {
type SeekFuture<'f>
= impl Future<Output = io::Result<()>> + 'f
= Ready<io::Result<()>>
where
Self: 'f;

type Future = impl Future<Output = io::Result<Option<(Self, BytesMut, usize)>>>;
type Future = BoxFuture<'static, io::Result<Option<(Self, BytesMut, usize)>>>;

fn seek(&mut self, pos: SeekFrom) -> Self::SeekFuture<'_> {
let SeekFrom::Start(pos) = pos else {
unreachable!("ChunkRead::seek only accept pos as SeekFrom::Start variant")
};
self.pos += pos;
async { Ok(()) }
ready(Ok(()))
}

fn next(mut self, buf: BytesMut) -> Self::Future {
async {
Box::pin(async {
let (res, buf) = self.file.read_at(buf, self.pos).await;
let n = res?;
if n == 0 {
Expand All @@ -220,7 +244,7 @@ mod tokio_uring_impl {
self.pos += n as u64;
Ok(Some((self, buf, n)))
}
}
})
}
}
}
2 changes: 1 addition & 1 deletion web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ file = ["file-raw", "http-file/default"]
# static file serving with io-uring
file-io-uring = ["io-uring", "file", "http-file/tokio-uring"]
# static file serving without default file system
file-raw = ["http-file", "nightly"]
file-raw = ["http-file"]

# rate-limit middleware
rate-limit = ["http-rate"]
Expand Down

0 comments on commit 7645226

Please sign in to comment.