#include <boost/asio/spawn.hpp>
#include "cancel_on_error.h"
#include "co_throttle.h"
-#include "yield_context.h"
#include "spawn_throttle.h"
namespace ceph::async {
/// \code
/// void child(task& t, boost::asio::yield_context yield);
///
-/// void parent(std::span<task> tasks, optional_yield y)
+/// void parent(std::span<task> tasks, boost::asio::yield_context yield)
/// {
/// // process all tasks, up to 10 at a time
-/// max_concurrent_for_each(tasks, 10, y, child);
+/// max_concurrent_for_each(tasks, 10, yield, child);
/// }
/// \endcode
template <typename Iterator, typename Sentinel, typename Func,
void max_concurrent_for_each(Iterator begin,
Sentinel end,
size_t max_concurrent,
- optional_yield y,
+ boost::asio::yield_context yield,
Func&& func,
cancel_on_error on_error = cancel_on_error::none)
{
if (begin == end) {
return;
}
- auto throttle = spawn_throttle{y, max_concurrent, on_error};
+ auto throttle = spawn_throttle{yield, max_concurrent, on_error};
for (Iterator i = begin; i != end; ++i) {
throttle.spawn([&func, &val = *i] (boost::asio::yield_context yield) {
func(val, yield);
std::invocable<Func, Reference, boost::asio::yield_context>)
auto max_concurrent_for_each(Range&& range,
size_t max_concurrent,
- optional_yield y,
+ boost::asio::yield_context yield,
Func&& func,
cancel_on_error on_error = cancel_on_error::none)
{
return max_concurrent_for_each(std::begin(range), std::end(range),
- max_concurrent, y, std::forward<Func>(func),
- on_error);
+ max_concurrent, yield,
+ std::forward<Func>(func), on_error);
}
// \overload
bool operator==(const char* c, null_sentinel) { return !*c; }
static_assert(std::sentinel_for<null_sentinel, const char*>);
-TEST(iterator_null_yield, empty)
-{
- int* end = nullptr;
- auto cr = [] (int, asio::yield_context) {};
- max_concurrent_for_each(end, end, 10, null_yield, cr);
-}
-
-TEST(iterator_null_yield, over_limit)
-{
- int concurrent = 0;
- int max_concurrent = 0;
- int completed = 0;
-
- auto cr = [&] (int, asio::yield_context yield) {
- ++concurrent;
- if (max_concurrent < concurrent) {
- max_concurrent = concurrent;
- }
-
- wait_for(1ms, yield);
-
- --concurrent;
- ++completed;
- };
-
- constexpr auto arr = std::array{1,2,3,4,5,6,7,8,9,10};
- max_concurrent_for_each(begin(arr), end(arr), 2, null_yield, cr);
-
- EXPECT_EQ(0, concurrent);
- EXPECT_EQ(2, max_concurrent);
- EXPECT_EQ(10, completed);
-}
-
-TEST(iterator_null_yield, sentinel)
-{
- const char* begin = "hello";
- null_sentinel end;
-
- size_t completed = 0;
- auto cr = [&completed] (char c, asio::yield_context) { ++completed; };
- max_concurrent_for_each(begin, end, 10, null_yield, cr);
- EXPECT_EQ(completed, 5);
-}
-
-TEST(range_null_yield, empty)
-{
- constexpr std::array<int, 0> arr{};
- auto cr = [] (int, asio::yield_context) {};
- max_concurrent_for_each(arr, 10, null_yield, cr);
-}
-
-TEST(range_null_yield, over_limit)
-{
- int concurrent = 0;
- int max_concurrent = 0;
- int completed = 0;
-
- auto cr = [&] (int, asio::yield_context yield) {
- ++concurrent;
- if (max_concurrent < concurrent) {
- max_concurrent = concurrent;
- }
-
- wait_for(1ms, yield);
-
- --concurrent;
- ++completed;
- };
-
- constexpr auto arr = std::array{1,2,3,4,5,6,7,8,9,10};
- max_concurrent_for_each(arr, 2, null_yield, cr);
-
- EXPECT_EQ(0, concurrent);
- EXPECT_EQ(2, max_concurrent);
- EXPECT_EQ(10, completed);
-}
-
-
TEST(iterator_yield, empty)
{
int* end = nullptr;