-
Notifications
You must be signed in to change notification settings - Fork 517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core)!: implement write returns metadata #5562
base: main
Are you sure you want to change the base?
Conversation
8591861
to
5c98d37
Compare
Well, well, well... Let's do our best to permit this since it's not harmful. Technically, we don't allow users to parse the ETag value; instead, they should store it and compare it with values from the same source. I'm guessing the issue lies in part of our code assuming that the ETag must contain |
No. The issue is that I compare the Etag from |
That's really surprising. Let's disable the Ceph RADOS test and create an issue to track it. I believe such a bug isn't worth our workaround. |
The results are the same across Ceph RADOS, Minio and S3 |
81aeb13
to
ddc3de5
Compare
I still created a workaround by adding prefix and suffix " for Etag in the test if they are not included. I think this approach is simpler, what do you think ? |
core/src/raw/adapters/kv/backend.rs
Outdated
self.kv.set(&self.path, buf).await | ||
self.kv.set(&self.path, buf).await?; | ||
|
||
Ok(Metadata::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can return at least the content length of file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally, I planned to leave this for later PRs, as I was only prepared to implement the logic for S3
. However, since content_length
is not an Option
, I agree with you - it's better to return content_length
as the very least; otherwise users might be confused by the zero length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But there is still an issue - what about append
? Can we have a simple method to retrieve the content_length
without performing a stat
or parsing the result of append
?
core/src/raw/adapters/kv/backend.rs
Outdated
let buf = self.buffer.clone().collect(); | ||
self.kv.blocking_set(&self.path, buf)?; | ||
Ok(()) | ||
Ok(Metadata::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same.
@@ -301,7 +301,8 @@ impl<S: Adapter> oio::Write for KvWriter<S> { | |||
} | |||
}; | |||
self.kv.set(&self.path, value).await?; | |||
Ok(()) | |||
|
|||
Ok(Metadata::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can return back the metadata in value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, thank you.
@@ -330,7 +331,7 @@ impl<S: Adapter> oio::BlockingWrite for KvWriter<S> { | |||
}; | |||
|
|||
kv.blocking_set(&self.path, value)?; | |||
Ok(()) | |||
Ok(Metadata::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same.
async fn close(&mut self) -> Result<()> { | ||
Ok(()) | ||
async fn close(&mut self) -> Result<Metadata> { | ||
Ok(Metadata::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should return valid data here. The metadata could be returned and replaced by self.inner.append().await
, then stored within AppendWriter
until the user calls close
.
let (Some(upload_id), Some(file_id)) = (self.upload_id.as_ref(), self.file_id.as_ref()) | ||
else { | ||
return Ok(()); | ||
return Ok(Metadata::default()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to set a content length for each service, at the very least. content_length
is specifically handled in OpenDAL, where users will receive 0
if it doesn't set.
if !maybe_error.code.is_empty() { | ||
return Err(from_s3_error(maybe_error, parts)); | ||
} | ||
|
||
Ok(()) | ||
let ret: CompleteMultipartUploadResult = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can embed the error struct in CompleteMultipartUploadResult
so that we don't need to parse twice.
core/tests/behavior/async_write.rs
Outdated
last_modified_time | ||
); | ||
} | ||
if let Some(etag) = meta.etag() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to comment this test until rados fix it.
core/tests/behavior/async_write.rs
Outdated
assert_eq!(stat_meta.content_length(), meta.content_length()); | ||
} | ||
if let Some(last_modified_time) = meta.last_modified() { | ||
assert_eq!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's more readable to use the following?
assert_eq!(meta.last_modified(), stat_meta.last_modified())
Perhaps we should introduce |
Would
if a service returns
Make sense ! Making it explicit is better. |
Wow, they've already had a PR for this issue: ceph/ceph#60477 |
Gently push. Hi, @Xuanwo I've provided some replies, do you have any suggestions ? |
I prefer to align with exists
That's nice, maybe we can disable ceph test for now... |
ddc3de5
to
a1e0b0a
Compare
Which issue does this PR close?
Part of #5557
Rationale for this change
What changes are included in this PR?
write returns metadata
forOperator
andBlockingOperator
write_has_content_length
for all services and implement the logic for themwrite returns metadata
logic for serviceS3
,fs
,monoiofs
andwebhdfs
Metadata
after writingAre there any user-facing changes?
Yes.
write
,write_with
inOperator
returnsResult<Metadata>
instead ofReturn<()>
Writer.close()
returnsReturn<Metadata>
instead ofReturn<()>
write
inBlockingOperator
returnsReturn<Metadata>
instead ofReturn<()>
FunctionWrite.call()
used byBlockingOperator
returnsReturn<Metadata>
instead ofReturn<()>