Skip to content

[C++] FS: Would S3 OutputStream CloseAsync meets lifetime issue? #37670

@mapleFU

Description

@mapleFU

Describe the enhancement requested

During CloseAsync:

  Future<> CloseAsync() override {
    if (closed_) return Status::OK();

    if (current_part_) {
      // Upload last part
      RETURN_NOT_OK(CommitCurrentPart());
    }

    // S3 mandates at least one part, upload an empty one if necessary
    if (part_number_ == 1) {
      RETURN_NOT_OK(UploadPart("", 0));
    }

    // Wait for in-progress uploads to finish (if async writes are enabled)
    return FlushAsync().Then([this]() {
      ARROW_ASSIGN_OR_RAISE(auto client_lock, holder_->Lock());

      // At this point, all part uploads have finished successfully
      DCHECK_GT(part_number_, 1);
      DCHECK_EQ(upload_state_->completed_parts.size(),
                static_cast<size_t>(part_number_ - 1));

      S3Model::CompletedMultipartUpload completed_upload;
      completed_upload.SetParts(upload_state_->completed_parts);
      S3Model::CompleteMultipartUploadRequest req;
      req.SetBucket(ToAwsString(path_.bucket));
      req.SetKey(ToAwsString(path_.key));
      req.SetUploadId(upload_id_);
      req.SetMultipartUpload(std::move(completed_upload));

      auto outcome =
          client_lock.Move()->CompleteMultipartUploadWithErrorFixup(std::move(req));
      if (!outcome.IsSuccess()) {
        return ErrorToStatus(
            std::forward_as_tuple("When completing multiple part upload for key '",
                                  path_.key, "' in bucket '", path_.bucket, "': "),
            "CompleteMultipartUpload", outcome.GetError());
      }

      holder_ = nullptr;
      closed_ = true;
      return Status::OK();
    });
  }

Notice that in FlushAsync().Then, the lambda capture this. When:

  1. user call FlushAsync()
  2. destruct OutputStream without waiting for future
  3. Call Then([this]()...

Would this raise lifetime problem? Or here is some lifetime constraint I didn't catch?

Component(s)

C++

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions