iceberg-cpp
Loading...
Searching...
No Matches
task_group.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
22#include <concepts>
23#include <optional>
24#include <type_traits>
25#include <utility>
26#include <vector>
27
28#include "iceberg/iceberg_export.h"
29#include "iceberg/result.h"
30#include "iceberg/util/executor.h"
31#include "iceberg/util/functional.h"
32#include "iceberg/util/retry_util.h"
33
34namespace iceberg {
35
36namespace internal {
37
38template <typename F>
40
41template <typename T>
43 std::is_invocable_r_v<Status, const T&> ||
44 (std::copy_constructible<T> && std::is_invocable_r_v<Status, T&>);
45
46template <typename F>
47concept RetryableStatusTask = std::constructible_from<std::remove_cvref_t<F>, F> &&
49
50ICEBERG_EXPORT Status RunTasksSingleThreaded(std::vector<FnOnce<Status()>> tasks);
51
52ICEBERG_EXPORT Status RunTasksParallel(Executor& executor,
53 std::vector<FnOnce<Status()>> tasks);
54
55} // namespace internal
56
57template <retry::Policy RetryPolicy = retry::NoRetry>
58class ICEBERG_TEMPLATE_CLASS_EXPORT TaskGroup {
59 private:
60 static constexpr bool kRetryEnabled = !std::same_as<RetryPolicy, retry::NoRetry>;
61
62 struct Empty {};
63
64 using RetryConfigStorage = std::conditional_t<kRetryEnabled, RetryConfig, Empty>;
65
66 public:
67 TaskGroup() = default;
68
69 explicit TaskGroup(RetryConfig retry_config)
70 requires(kRetryEnabled)
71 : retry_config_(std::move(retry_config)) {}
72
73 auto&& SetExecutor(this auto&& self, OptionalExecutor executor) {
74 self.executor_ = std::move(executor);
75 return std::forward<decltype(self)>(self);
76 }
77
78 template <typename F>
79 requires((!kRetryEnabled && internal::OnceStatusTask<F>) ||
80 (kRetryEnabled && internal::RetryableStatusTask<F>))
81 auto&& Submit(this auto&& self, F&& task) {
82 self.tasks_.emplace_back([&] {
83 if constexpr (!kRetryEnabled) {
84 return std::forward<F>(task);
85 } else {
86 return [retry_config = self.retry_config_,
87 task = std::forward<F>(task)]() mutable -> Status {
88 return RetryRunner<RetryPolicy>(retry_config).Run(task);
89 };
90 }
91 }());
92 return std::forward<decltype(self)>(self);
93 }
94
95 Status Run() && {
96 if (!executor_.has_value()) {
97 return internal::RunTasksSingleThreaded(std::move(tasks_));
98 }
99 return internal::RunTasksParallel(executor_->get(), std::move(tasks_));
100 }
101
102 private:
103 std::vector<FnOnce<Status()>> tasks_;
104 OptionalExecutor executor_;
105 [[no_unique_address]] RetryConfigStorage retry_config_;
106};
107
108} // namespace iceberg
Definition functional.h:45
Definition task_group.h:58
Definition task_group.h:39
Definition task_group.h:42
Definition task_group.h:47
Definition functional.h:38
Configuration for retry behavior.
Definition retry_util.h:43