Skip to content

Commit 1175ed8

Browse files
aawsomesimonsan
andauthored
fix(commands): Use spawn_blocking in webdav when calling rustic_core (#1365)
(after reverting #1361) solves the webdav problem reported in #1181 Co-authored-by: simonsan <[email protected]>
1 parent 984c048 commit 1175ed8

File tree

1 file changed

+53
-28
lines changed

1 file changed

+53
-28
lines changed

src/commands/webdav/webdavfs.rs

+53-28
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ use dav_server::{
1616
},
1717
};
1818
use futures::FutureExt;
19-
2019
use rustic_core::{
2120
repofile::Node,
2221
vfs::{FilePolicy, OpenFile, Vfs},
2322
IndexedFull, Repository,
2423
};
24+
use tokio::task::spawn_blocking;
2525

2626
fn now() -> SystemTime {
2727
static NOW: OnceLock<SystemTime> = OnceLock::new();
@@ -55,7 +55,7 @@ pub struct WebDavFS<P, S> {
5555
inner: Arc<DavFsInner<P, S>>,
5656
}
5757

58-
impl<P, S: IndexedFull> WebDavFS<P, S> {
58+
impl<P: Send + Sync + 'static, S: IndexedFull + Send + Sync + 'static> WebDavFS<P, S> {
5959
/// Create a new [`WebDavFS`] instance.
6060
///
6161
/// # Arguments
@@ -94,11 +94,17 @@ impl<P, S: IndexedFull> WebDavFS<P, S> {
9494
/// The [`Node`] at the specified path
9595
///
9696
/// [`Tree`]: crate::repofile::Tree
97-
fn node_from_path(&self, path: &DavPath) -> Result<Node, FsError> {
98-
self.inner
99-
.vfs
100-
.node_from_path(&self.inner.repo, &path.as_pathbuf())
101-
.map_err(|_| FsError::GeneralFailure)
97+
async fn node_from_path(&self, path: &DavPath) -> Result<Node, FsError> {
98+
let inner = self.inner.clone();
99+
let path = path.as_pathbuf();
100+
spawn_blocking(move || {
101+
inner
102+
.vfs
103+
.node_from_path(&inner.repo, &path)
104+
.map_err(|_| FsError::GeneralFailure)
105+
})
106+
.await
107+
.map_err(|_| FsError::GeneralFailure)?
102108
}
103109

104110
/// Get a list of [`Node`]s from the specified directory path.
@@ -116,11 +122,17 @@ impl<P, S: IndexedFull> WebDavFS<P, S> {
116122
/// The list of [`Node`]s at the specified path
117123
///
118124
/// [`Tree`]: crate::repofile::Tree
119-
fn dir_entries_from_path(&self, path: &DavPath) -> Result<Vec<Node>, FsError> {
120-
self.inner
121-
.vfs
122-
.dir_entries_from_path(&self.inner.repo, &path.as_pathbuf())
123-
.map_err(|_| FsError::GeneralFailure)
125+
async fn dir_entries_from_path(&self, path: &DavPath) -> Result<Vec<Node>, FsError> {
126+
let inner = self.inner.clone();
127+
let path = path.as_pathbuf();
128+
spawn_blocking(move || {
129+
inner
130+
.vfs
131+
.dir_entries_from_path(&inner.repo, &path)
132+
.map_err(|_| FsError::GeneralFailure)
133+
})
134+
.await
135+
.map_err(|_| FsError::GeneralFailure)?
124136
}
125137
}
126138

@@ -141,7 +153,7 @@ impl<P: Debug + Send + Sync + 'static, S: IndexedFull + Debug + Send + Sync + 's
141153

142154
fn symlink_metadata<'a>(&'a self, davpath: &'a DavPath) -> FsFuture<'_, Box<dyn DavMetaData>> {
143155
async move {
144-
let node = self.node_from_path(davpath)?;
156+
let node = self.node_from_path(davpath).await?;
145157
let meta: Box<dyn DavMetaData> = Box::new(DavFsMetaData(node));
146158
Ok(meta)
147159
}
@@ -154,7 +166,7 @@ impl<P: Debug + Send + Sync + 'static, S: IndexedFull + Debug + Send + Sync + 's
154166
_meta: ReadDirMeta,
155167
) -> FsFuture<'_, FsStream<Box<dyn DavDirEntry>>> {
156168
async move {
157-
let entries = self.dir_entries_from_path(davpath)?;
169+
let entries = self.dir_entries_from_path(davpath).await?;
158170
let entry_iter = entries.into_iter().map(|e| {
159171
let entry: Box<dyn DavDirEntry> = Box::new(DavFsDirEntry(e));
160172
Ok(entry)
@@ -180,19 +192,25 @@ impl<P: Debug + Send + Sync + 'static, S: IndexedFull + Debug + Send + Sync + 's
180192
return Err(FsError::Forbidden);
181193
}
182194

183-
let node = self.node_from_path(path)?;
195+
let node = self.node_from_path(path).await?;
184196
if matches!(self.inner.file_policy, FilePolicy::Forbidden) {
185197
return Err(FsError::Forbidden);
186198
}
187199

188-
let open = self
189-
.inner
190-
.repo
191-
.open_file(&node)
192-
.map_err(|_err| FsError::GeneralFailure)?;
200+
let inner = self.inner.clone();
201+
let node_copy = node.clone();
202+
let open = spawn_blocking(move || {
203+
inner
204+
.repo
205+
.open_file(&node_copy)
206+
.map_err(|_err| FsError::GeneralFailure)
207+
})
208+
.await
209+
.map_err(|_| FsError::GeneralFailure)??;
210+
193211
let file: Box<dyn DavFile> = Box::new(DavFsFile {
194212
node,
195-
open,
213+
open: Arc::new(open),
196214
fs: self.inner.clone(),
197215
seek: 0,
198216
});
@@ -239,7 +257,7 @@ struct DavFsFile<P, S> {
239257
node: Node,
240258

241259
/// The [`OpenFile`] for this file
242-
open: OpenFile,
260+
open: Arc<OpenFile>,
243261

244262
/// The [`DavFsInner`] this file belongs to
245263
fs: Arc<DavFsInner<P, S>>,
@@ -254,7 +272,9 @@ impl<P, S> Debug for DavFsFile<P, S> {
254272
}
255273
}
256274

257-
impl<P: Debug + Send + Sync, S: IndexedFull + Debug + Send + Sync> DavFile for DavFsFile<P, S> {
275+
impl<P: Debug + Send + Sync + 'static, S: IndexedFull + Debug + Send + Sync + 'static> DavFile
276+
for DavFsFile<P, S>
277+
{
258278
fn metadata(&mut self) -> FsFuture<'_, Box<dyn DavMetaData>> {
259279
async move {
260280
let meta: Box<dyn DavMetaData> = Box::new(DavFsMetaData(self.node.clone()));
@@ -272,12 +292,17 @@ impl<P: Debug + Send + Sync, S: IndexedFull + Debug + Send + Sync> DavFile for D
272292
}
273293

274294
fn read_bytes(&mut self, count: usize) -> FsFuture<'_, Bytes> {
295+
let fs = self.fs.clone();
296+
let seek = self.seek;
297+
let open = self.open.clone();
275298
async move {
276-
let data = self
277-
.fs
278-
.repo
279-
.read_file_at(&self.open, self.seek, count)
280-
.map_err(|_err| FsError::GeneralFailure)?;
299+
let data = spawn_blocking(move || {
300+
fs.repo
301+
.read_file_at(&open, seek, count)
302+
.map_err(|_err| FsError::GeneralFailure)
303+
})
304+
.await
305+
.map_err(|_| FsError::GeneralFailure)??;
281306
self.seek += data.len();
282307
Ok(data)
283308
}

0 commit comments

Comments
 (0)