@@ -69,6 +69,58 @@ namespace internal {
6969
7070class ParallelObjectWriteStreambuf ;
7171
72+ // Type-erased function object to execute ComposeMany with most arguments
73+ // bound.
74+ using Composer = std::function<StatusOr<ObjectMetadata>(
75+ std::vector<ComposeSourceObject> const &)>;
76+
77+ // The `ObjectWriteStream`s have to hold references to the state of
78+ // the parallel upload so that they can update it when finished and trigger
79+ // shards composition, hence `ResumableParallelUploadState` has to be
80+ // destroyed after the `ObjectWriteStream`s.
81+ // `ResumableParallelUploadState` and `ObjectWriteStream`s are passed
82+ // around by values, so we don't control their lifetime. In order to
83+ // circumvent it, we move the state to something held by a `shared_ptr`.
84+ class ParallelUploadStateImpl
85+ : public std::enable_shared_from_this<ParallelUploadStateImpl> {
86+ public:
87+ ParallelUploadStateImpl (std::string destination_object_name,
88+ std::shared_ptr<ScopedDeleter> deleter,
89+ Composer composer);
90+ ~ParallelUploadStateImpl ();
91+
92+ StatusOr<ObjectWriteStream> CreateStream (
93+ RawClient& raw_client, ResumableUploadRequest const & request);
94+
95+ void StreamFinished (std::size_t stream_idx,
96+ StatusOr<ResumableUploadResponse> const & response);
97+
98+ future<StatusOr<ObjectMetadata>> WaitForCompletion () const ;
99+
100+ Status EagerCleanup ();
101+
102+ void Fail (Status status);
103+
104+ private:
105+ mutable std::mutex mu_;
106+ // Promises made via `WaitForCompletion()`
107+ mutable std::vector<promise<StatusOr<ObjectMetadata>>> res_promises_;
108+ // Type-erased object for deleting temporary objects.
109+ std::shared_ptr<ScopedDeleter> deleter_;
110+ // Type-erased function object to execute ComposeMany with most arguments
111+ // bound.
112+ std::function<StatusOr<ObjectMetadata>(std::vector<ComposeSourceObject>)>
113+ composer_;
114+ std::string destination_object_name_;
115+ // Set when all streams are closed and composed but before cleanup.
116+ bool finished_;
117+ // Tracks how many streams are still written to.
118+ std::size_t num_unfinished_streams_;
119+ std::vector<ComposeSourceObject> to_compose_;
120+ google::cloud::optional<StatusOr<ObjectMetadata>> res_;
121+ Status cleanup_status_;
122+ };
123+
72124struct ComposeManyApplyHelper {
73125 template <typename ... Options>
74126 StatusOr<ObjectMetadata> operator ()(Options&&... options) const {
@@ -168,62 +220,15 @@ class NonResumableParallelUploadState {
168220 void Fail (Status status) { return impl_->Fail (std::move (status)); }
169221
170222 private:
171- // Type-erased function object to execute ComposeMany with most arguments
172- // bound.
173- using Composer = std::function<StatusOr<ObjectMetadata>(
174- std::vector<ComposeSourceObject> const &)>;
175-
176- // The `ObjectWriteStream`s have to hold references to the state of
177- // the parallel upload so that they can update it when finished and trigger
178- // shards composition, hence `NonResumableParallelUploadState` has to be
179- // destroyed after the `ObjectWriteStream`s.
180- // `NonResumableParallelUploadState` and `ObjectWriteStream`s are passed
181- // around by values, so we don't control their lifetime. In order to
182- // circumvent it, we move the state to something held by a `shared_ptr`.
183- class Impl : public std ::enable_shared_from_this<Impl> {
184- public:
185- Impl (std::unique_ptr<ScopedDeleter> deleter, Composer composer);
186- ~Impl ();
187-
188- StatusOr<ObjectWriteStream> CreateStream (
189- RawClient& raw_client, ResumableUploadRequest const & request);
190-
191- void StreamFinished (std::size_t stream_idx,
192- StatusOr<ResumableUploadResponse> const & response);
193-
194- future<StatusOr<ObjectMetadata>> WaitForCompletion () const ;
195-
196- Status EagerCleanup ();
197-
198- void Fail (Status status);
199-
200- private:
201- mutable std::mutex mu_;
202- // Promises made via `WaitForCompletion()`
203- mutable std::vector<promise<StatusOr<ObjectMetadata>>> res_promises_;
204- // Type-erased object for deleting temporary objects.
205- std::unique_ptr<ScopedDeleter> deleter_;
206- // Type-erased function object to execute ComposeMany with most arguments
207- // bound.
208- std::function<StatusOr<ObjectMetadata>(std::vector<ComposeSourceObject>)>
209- composer_;
210- // Set when all streams are closed and composed but before cleanup.
211- bool finished_;
212- // Tracks how many streams are still written to.
213- std::size_t num_unfinished_streams_;
214- std::vector<ComposeSourceObject> to_compose_;
215- google::cloud::optional<StatusOr<ObjectMetadata>> res_;
216- Status cleanup_status_;
217- };
218-
219- NonResumableParallelUploadState (std::shared_ptr<Impl> state,
220- std::vector<ObjectWriteStream> shards)
223+ NonResumableParallelUploadState (
224+ std::shared_ptr<ParallelUploadStateImpl> state,
225+ std::vector<ObjectWriteStream> shards)
221226 : impl_(std::move(state)), shards_(std::move(shards)) {}
222227
223- std::shared_ptr<Impl > impl_;
228+ std::shared_ptr<ParallelUploadStateImpl > impl_;
224229 std::vector<ObjectWriteStream> shards_;
225230
226- friend class ParallelObjectWriteStreambuf ;
231+ friend class NonResumableParallelObjectWriteStreambuf ;
227232};
228233
229234/* *
@@ -306,8 +311,8 @@ NonResumableParallelUploadState::Create(Client client,
306311 }
307312 deleter->Add (*lock);
308313
309- auto internal_state = std::make_shared<NonResumableParallelUploadState::Impl >(
310- std::move (deleter), std::move (composer));
314+ auto internal_state = std::make_shared<ParallelUploadStateImpl >(
315+ object_name, std::move (deleter), std::move (composer));
311316 std::vector<ObjectWriteStream> streams;
312317
313318 auto upload_options = StaticTupleFilter<
0 commit comments