This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new f7f9990f9 fix(integration/object_store): object_store requires
metadata in list (#5501)
f7f9990f9 is described below
commit f7f9990f95146400c3aef8afc11804e4a6e3afe3
Author: Xuanwo <[email protected]>
AuthorDate: Fri Jan 3 15:49:35 2025 +0800
fix(integration/object_store): object_store requires metadata in list
(#5501)
---
integrations/object_store/src/store.rs | 73 +++++++++++++++++++++++-----------
integrations/object_store/src/utils.rs | 12 +-----
2 files changed, 51 insertions(+), 34 deletions(-)
diff --git a/integrations/object_store/src/store.rs
b/integrations/object_store/src/store.rs
index c5ba9a675..32ccbc2d8 100644
--- a/integrations/object_store/src/store.rs
+++ b/integrations/object_store/src/store.rs
@@ -323,32 +323,52 @@ impl ObjectStore for OpendalStore {
let offset = offset.clone();
let fut = async move {
- let fut = if
self.inner.info().full_capability().list_with_start_after {
- self.inner
- .lister_with(&path)
- .start_after(offset.as_ref())
- .recursive(true)
- .into_future()
- .into_send()
- .await
- .map_err(|err| format_object_store_error(err, &path))?
- .then(try_format_object_meta)
- .into_send()
- .boxed()
+ let list_with_start_after =
self.inner.info().full_capability().list_with_start_after;
+ let mut fut = self.inner.lister_with(&path).recursive(true);
+
+ // Use native start_after support if possible.
+ if list_with_start_after {
+ fut = fut.start_after(offset.as_ref());
+ }
+
+ let lister = fut
+ .await
+ .map_err(|err| format_object_store_error(err, &path))?
+ .then(move |entry| {
+ let path = path.clone();
+
+ async move {
+ let entry = entry.map_err(|err|
format_object_store_error(err, &path))?;
+ let (path, metadata) = entry.into_parts();
+
+ // If it's a dir or last_modified is present, we can
use it directly.
+ if metadata.is_dir() ||
metadata.last_modified().is_some() {
+ let object_meta = format_object_meta(&path,
&metadata);
+ return Ok(object_meta);
+ }
+
+ let metadata = self
+ .inner
+ .stat(&path)
+ .await
+ .map_err(|err| format_object_store_error(err,
&path))?;
+ let object_meta = format_object_meta(&path, &metadata);
+ Ok::<_, object_store::Error>(object_meta)
+ }
+ })
+ .into_send()
+ .boxed();
+
+ let stream = if list_with_start_after {
+ lister
} else {
- self.inner
- .lister_with(&path)
- .recursive(true)
- .into_future()
- .into_send()
- .await
- .map_err(|err| format_object_store_error(err, &path))?
- .try_filter(move |entry|
futures::future::ready(entry.path() > offset.as_ref()))
- .then(try_format_object_meta)
+ lister
+ .try_filter(move |entry|
futures::future::ready(entry.location > offset))
.into_send()
.boxed()
};
- Ok::<_, object_store::Error>(fut)
+
+ Ok::<_, object_store::Error>(stream)
};
fut.into_stream().into_send().try_flatten().boxed()
@@ -374,8 +394,15 @@ impl ObjectStore for OpendalStore {
if meta.is_dir() {
common_prefixes.push(entry.path().into());
- } else {
+ } else if meta.last_modified().is_some() {
objects.push(format_object_meta(entry.path(), meta));
+ } else {
+ let meta = self
+ .inner
+ .stat(entry.path())
+ .await
+ .map_err(|err| format_object_store_error(err,
entry.path()))?;
+ objects.push(format_object_meta(entry.path(), &meta));
}
}
diff --git a/integrations/object_store/src/utils.rs
b/integrations/object_store/src/utils.rs
index 5eb4a10f7..63357402b 100644
--- a/integrations/object_store/src/utils.rs
+++ b/integrations/object_store/src/utils.rs
@@ -17,7 +17,7 @@
use futures::Stream;
use object_store::ObjectMeta;
-use opendal::{Entry, Metadata};
+use opendal::Metadata;
use std::future::IntoFuture;
/// Conditionally add the `Send` marker trait for the wrapped type.
@@ -60,16 +60,6 @@ pub fn format_object_meta(path: &str, meta: &Metadata) ->
ObjectMeta {
}
}
-/// Try to format `opendal::Entry` to `object_store::ObjectMeta`.
-pub async fn try_format_object_meta(
- res: object_store::Result<Entry, opendal::Error>,
-) -> object_store::Result<ObjectMeta> {
- let entry = res.map_err(|err| format_object_store_error(err, ""))?;
- let meta = entry.metadata();
-
- Ok(format_object_meta(entry.path(), meta))
-}
-
/// Make given future `Send`.
pub trait IntoSendFuture {
type Output;