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
Add support for remote global order writes #3393
Conversation
This pull request has been linked to Shortcut Story #10668: Implement serialization for global order writes.. |
test/src/unit-capi-array.cc
Outdated
// rc = tiledb_query_finalize(ctx_, query); | ||
// CHECK(rc == TILEDB_OK); | ||
// TODO: Bug, wrong results | ||
submit_serialized_query(ctx_, query); |
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.
In create_dense_vector, set the capacity to 10 on the array schema. Should fix this case.
8f5c5f1
to
018d6b6
Compare
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.
Initial feedback... Amazing progress!!
Query* query, | ||
bool clientside); | ||
|
||
int serialize_query( |
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.
Doxygen doc.
void submit_and_finalize_serialized_query( | ||
tiledb_ctx_t* ctx, tiledb_query_t* query); | ||
|
||
void submit_and_finalize_serialized_query(const Context& ctx, Query& query); |
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.
NIT: line break between function and doc for the next.
test/src/unit-capi-any.cc
Outdated
REQUIRE(rc == TILEDB_OK); | ||
rc = tiledb_query_finalize(ctx, query); // Second time must create no problem | ||
REQUIRE(rc == TILEDB_OK); | ||
// rc = tiledb_query_submit(ctx, query); |
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.
Remove commented lines everywhere.
@@ -1216,6 +1216,223 @@ void check_counts(span<T> vals, std::vector<uint64_t> expected) { | |||
CHECK(counts[i] == expected[i]); | |||
} | |||
} | |||
void serialize_query( |
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.
Are these just moving of the code in test/src/unit-capi-serialized_queries.cc?
@@ -54,6 +54,10 @@ | |||
using namespace tiledb; | |||
using ResultSetType = std::map<std::string, std::any>; | |||
|
|||
using tiledb::test::allocate_query_buffers; |
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.
Can we change to just using tiledb::test?
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've noticed this could be cleaned up in other files as well.
@@ -815,6 +823,141 @@ class FragmentMetadata { | |||
*/ | |||
const shared_ptr<const ArraySchema>& array_schema() const; | |||
|
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.
As this is only used for serialization, instead of writing all those accessors, it might be better to create a new object that will contain references to all of those. That way when we move to the new serialization standard, we don't have to come in and remove all those unused methods.
I'm also not a big fan of having reference accessors that are used to modify the internal state of the object, I know this might be a lot of work but maybe it would be a worthy investment to make a constructor taking in everything needed from deserialization to create a fully functional FragmentMetadata object? This would get rid of the need for set_schema_name and set_dense for example.
tiledb/sm/query/domain_buffer.h
Outdated
@@ -155,6 +190,16 @@ class SingleCoord { | |||
return &qb_[d]; | |||
} | |||
|
|||
inline const std::vector<std::vector<uint8_t>>& get_coords() const { |
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.
Whatever we decide for the fragment metadata accessors should be done here too.
@@ -1786,5 +1786,85 @@ Status VFS::write(const URI& uri, const void* buffer, uint64_t buffer_size) { | |||
Status_VFSError("Unsupported URI schemes: " + uri.to_string())); | |||
} | |||
|
|||
std::pair<Status, std::optional<VFS::MultiPartUploadState>> |
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.
Any chance this method could just throw and not return a pair?
@@ -671,6 +707,8 @@ class S3 { | |||
/** If !NOT_SET assign to bucket requests supporting SetACL() */ | |||
Aws::S3::Model::BucketCannedACL bucket_canned_acl_; | |||
|
|||
friend class VFS; |
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.
Could you comment why the friend declaration is needed?
|
||
if (array_->is_remote()) { | ||
auto rest_client = storage_manager_->rest_client(); | ||
if (rest_client == nullptr) |
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.
Remove one line ifs.
49cabd6
to
ebf2a27
Compare
05afd5d
to
607b9d4
Compare
45840e3
to
ecc66e9
Compare
global write tests to serializated roundtrip submits/finalize
also add cpp api for submit_and_finalize for easier testing
S3 bucket, key and status needs to be serialized as well. Code simplification. Getting s3 multipart state can be done with a single accessor function
When cloud executors die, context gets destructed, so S3::disconnect tries to complete multipart request
The coords_info_ markers need to be reset for remote global order writes too, otherwise the client fails a check for equal size input coords buffer between submits
query_to_capnp doesn't handle well uint32 offset buffers, so tiledb_buffer_list_flatten ends up overflowing the offset buffers
for remote global order writes. Standalone S3 global order writes should still buffer as normal
9eca90b
to
8d51519
Compare
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.
Some misc comments for follow-up.
status@4 :Text; | ||
completedParts@5 :List(CompletedPart); | ||
} | ||
struct CompletedPart { |
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.
Rename to S3CompletedPart?
@@ -361,6 +361,9 @@ class Query { | |||
/** Returns the array schema. */ | |||
const ArraySchema& array_schema() const; | |||
|
|||
/** Returns the array schema as a shared_ptr */ | |||
const std::shared_ptr<const ArraySchema> array_schema_shared() const; |
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.
This is a big code smell, in the future we should refactor rather than adding an accessor like this. The ownership here is problematic because the lifetime of a query has nothing to do with a fragment metadata (where this is used AFAICT).
return Status::Ok(); | ||
} | ||
|
||
Status Query::check_buffer_multipart_size() const { |
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.
Do we have test coverage for error handling in this situation? I don't think this check is sufficient, because a chunk may be smaller than 5 MB after compression.
if (strategy_ != nullptr) | ||
|
||
// When executed from serialization, resetting the strategy will delete | ||
// the fragment for global order writes. We need to prevent this, thus |
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.
Do you mind to clarify what fragment is this referring to?
@@ -2416,6 +2541,27 @@ tuple<Status, optional<bool>> Query::non_overlapping_ranges() { | |||
return subarray_.non_overlapping_ranges(storage_manager_->compute_tp()); | |||
} | |||
|
|||
bool Query::is_dense() const { | |||
return !coords_info_.has_coords_; |
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.
Can't we check the schema here instead? This is going to be wrong for dense queries with coordinate return for matching cells.
// If there is no entry for this uri, probably multipart upload is disabled | ||
// or no write was issued so far | ||
if (!state.has_value()) { | ||
return {Status::Ok(), {}}; |
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.
Shouldn't we continue
here?
return {Status::Ok(), nullopt}; | ||
} | ||
|
||
Status VFS::set_multipart_upload_state( |
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 this is going to fail with simultaneous queries. For now I think it would be fine to error out in that case, but I'm not sure where to introduce the synchronization point to catch the situation.
TYPE: FEATURE
DESC: Add support for remote global order writes