Conversation
There was a problem hiding this comment.
Pull Request Overview
Adds an optional async-fs based disk backend (feature flag asyncfs) to provide an async file implementation that does not depend on a Tokio reactor.
- Introduces AsyncFile wrapper and NativeFs implementation using async-fs.
- Adds feature flag and dependency wiring in Cargo.toml.
- Re-exports async-fs filesystem types when enabled.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| fusio/src/impls/disk/mod.rs | Adds asyncfs module and re-exports behind feature flag. |
| fusio/src/impls/disk/asyncfs/mod.rs | Implements AsyncFile with Read/Write traits using async-fs. |
| fusio/src/impls/disk/asyncfs/fs.rs | Implements NativeFs (Fs trait) using async-fs for filesystem operations. |
| fusio/Cargo.toml | Adds asyncfs feature and async-fs dependency. |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
fusio/src/impls/disk/asyncfs/mod.rs
Outdated
| let file = self.file.as_mut().expect("close file after closed"); | ||
| File::close(file).await?; |
There was a problem hiding this comment.
The close method does not set self.file to None after closing, so subsequent operations (which use unwrap/expect) will proceed on a closed handle and the panic messages like "write file after closed" will never trigger, leading instead to I/O errors on a logically closed file. Either remove the Option wrapper (if double-close protection is not required) or replace lines 52-53 with something like if let Some(file) = self.file.take() { file.close().await?; } to make the state transition explicit and future unwraps fail predictably.
| let file = self.file.as_mut().expect("close file after closed"); | |
| File::close(file).await?; | |
| if let Some(file) = self.file.take() { | |
| File::close(&file).await?; | |
| } else { | |
| panic!("close file after closed"); | |
| } |
| } else { | ||
| return Err(Error::Path(std::boxed::Box::new(io::Error::new( | ||
| io::ErrorKind::NotFound, | ||
| "Path not found and option.create is false", |
There was a problem hiding this comment.
The error message says "option.create" but the variable is options; adjust the message to "Path not found and options.create is false" (or reference the actual OpenOptions field name) for clarity.
| "Path not found and option.create is false", | |
| "Path not found and options.create is false", |
| } | ||
| } | ||
|
|
||
| let absolute_path = std::fs::canonicalize(&local_path).unwrap(); |
There was a problem hiding this comment.
unwrap() here can panic (e.g. race deletion, permission issues); propagate the error instead to avoid unexpected panics: let absolute_path = std::fs::canonicalize(&local_path).map_err(|e| Error::Path(Box::new(e)))?;.
| let absolute_path = std::fs::canonicalize(&local_path).unwrap(); | |
| let absolute_path = std::fs::canonicalize(&local_path) | |
| .map_err(|e| Error::Path(Box::new(e)))?; |
fusio/src/impls/disk/asyncfs/fs.rs
Outdated
| async fn open_options(&self, path: &Path, options: OpenOptions) -> Result<Self::File, Error> { | ||
| let local_path = | ||
| path_to_local(path).map_err(|err| Error::Path(std::boxed::Box::new(err)))?; | ||
| if !local_path.exists() { |
There was a problem hiding this comment.
local_path.exists() performs a blocking filesystem call in an async context; prefer using async_fs::metadata (and handling the error) to avoid a potential blocking operation on the async executor thread. Example: let exists = async_fs::metadata(&local_path).await.is_ok(); then branch on exists.
| if !local_path.exists() { | |
| if !async_fs::metadata(&local_path).await.is_ok() { |
|
Hi @bitdriftr , I'm absolutely insterested in another backend implementation, I'll take a look once it is ready for review. |
Hello, this PR adds a new disk implementation using async-fs. I want to support async-fs because it does not require a Tokio reactor, which I don't have in my current context.
This PR is gated behind a new feature
asyncfs.Let me know if you are interested in this feature. If so, I can work more on the PR to get it upstreamed.