aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/tests/coro/lazy
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@yahooinc.com>2022-11-04 15:53:27 +0000
committerHåvard Pettersen <havardpe@yahooinc.com>2022-11-04 15:58:07 +0000
commit695d581cde4c66b4405537fb3a0cdf6d25128a3b (patch)
treebf1c1913e4b55c48355d50229adea558f1e98d64 /vespalib/src/tests/coro/lazy
parent8ba46705190d62bcf9d398407331b1eab807ebd4 (diff)
wait for the completion of a Lazy<T> in non-coroutine code
Diffstat (limited to 'vespalib/src/tests/coro/lazy')
-rw-r--r--vespalib/src/tests/coro/lazy/lazy_test.cpp63
1 files changed, 54 insertions, 9 deletions
diff --git a/vespalib/src/tests/coro/lazy/lazy_test.cpp b/vespalib/src/tests/coro/lazy/lazy_test.cpp
index ead5e8e6427..ec27bf195ec 100644
--- a/vespalib/src/tests/coro/lazy/lazy_test.cpp
+++ b/vespalib/src/tests/coro/lazy/lazy_test.cpp
@@ -1,10 +1,11 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/coro/lazy.h>
-#include <vespa/vespalib/coro/sync_wait.h>
+#include <vespa/vespalib/coro/completion.h>
#include <vespa/vespalib/coro/schedule.h>
#include <vespa/vespalib/util/size_literals.h>
#include <vespa/vespalib/util/require.h>
+#include <vespa/vespalib/util/gate.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
#include <vespa/vespalib/gtest/gtest.h>
#include <mutex>
@@ -12,7 +13,9 @@
#include <thread>
using vespalib::Executor;
+using vespalib::Gate;
using vespalib::coro::Lazy;
+using vespalib::coro::Received;
using vespalib::coro::ScheduleFailedException;
using vespalib::coro::schedule;
using vespalib::coro::sync_wait;
@@ -56,7 +59,7 @@ Lazy<std::pair<bool,T>> try_schedule_on(Executor &executor, Lazy<T> value) {
std::cerr << "switching from thread " << std::this_thread::get_id() << std::endl;
bool accepted = co_await try_schedule(executor);
std::cerr << "........... to thread " << std::this_thread::get_id() << std::endl;
- co_return std::make_pair(accepted, co_await value);
+ co_return std::make_pair(accepted, co_await std::move(value));
}
template <typename T>
@@ -64,18 +67,18 @@ Lazy<T> schedule_on(Executor &executor, Lazy<T> value) {
std::cerr << "switching from thread " << std::this_thread::get_id() << std::endl;
co_await schedule(executor);
std::cerr << "........... to thread " << std::this_thread::get_id() << std::endl;
- co_return co_await value;
+ co_return co_await std::move(value);
}
TEST(LazyTest, simple_lazy_value) {
auto lazy = make_lazy(42);
- auto result = sync_wait(lazy);
+ auto result = sync_wait(std::move(lazy));
EXPECT_EQ(result, 42);
}
TEST(LazyTest, async_sum_of_async_values) {
auto lazy = async_add_values(10, 20);
- auto result = sync_wait(lazy);
+ auto result = sync_wait(std::move(lazy));
EXPECT_EQ(result, 30);
}
@@ -83,13 +86,13 @@ TEST(LazyTest, async_sum_of_external_async_values) {
auto a = make_lazy(100);
auto b = make_lazy(200);
auto lazy = async_sum(std::move(a), std::move(b));
- auto result = sync_wait(lazy);
+ auto result = sync_wait(std::move(lazy));
EXPECT_EQ(result, 300);
}
TEST(LazyTest, extract_rvalue_from_lazy_in_coroutine) {
auto lazy = extract_rvalue();
- auto result = sync_wait(lazy);
+ auto result = sync_wait(std::move(lazy));
EXPECT_EQ(result, 123);
}
@@ -110,7 +113,7 @@ TEST(LazyTest, calculate_result_in_another_thread) {
TEST(LazyTest, exceptions_are_propagated) {
vespalib::ThreadStackExecutor executor(1, 128_Ki);
auto lazy = try_schedule_on(executor, forward_value(will_throw()));
- EXPECT_THROW(sync_wait(lazy), vespalib::RequireFailedException);
+ EXPECT_THROW(sync_wait(std::move(lazy)), vespalib::RequireFailedException);
}
TEST(LazyTest, not_able_to_switch_thread_if_executor_is_shut_down) {
@@ -120,7 +123,49 @@ TEST(LazyTest, not_able_to_switch_thread_if_executor_is_shut_down) {
EXPECT_EQ(result.first, false);
EXPECT_EQ(result.second, 7);
auto lazy = schedule_on(executor, make_lazy(8));
- EXPECT_THROW(sync_wait(lazy), ScheduleFailedException);
+ EXPECT_THROW(sync_wait(std::move(lazy)), ScheduleFailedException);
+}
+
+TEST(LazyTest, async_wait_with_lambda) {
+ Gate gate;
+ Received<int> result;
+ vespalib::ThreadStackExecutor executor(1, 128_Ki);
+ auto lazy = schedule_on(executor, make_lazy(7));
+ async_wait(std::move(lazy), [&](auto res)
+ {
+ result = res;
+ gate.countDown();
+ });
+ gate.await();
+ EXPECT_EQ(result.get_value(), 7);
+}
+
+TEST(LazyTest, async_wait_with_error) {
+ Gate gate;
+ Received<int> result;
+ vespalib::ThreadStackExecutor executor(1, 128_Ki);
+ auto lazy = schedule_on(executor, will_throw());
+ async_wait(std::move(lazy), [&](auto res)
+ {
+ result = res;
+ gate.countDown();
+ });
+ gate.await();
+ EXPECT_THROW(result.get_value(), vespalib::RequireFailedException);
+}
+
+TEST(LazyTest, async_wait_with_move_only_result) {
+ Gate gate;
+ Received<std::unique_ptr<int>> result;
+ vespalib::ThreadStackExecutor executor(1, 128_Ki);
+ auto lazy = schedule_on(executor, move_only_int());
+ async_wait(std::move(lazy), [&](auto res)
+ {
+ result = std::move(res);
+ gate.countDown();
+ });
+ gate.await();
+ EXPECT_EQ(*(result.get_value()), 123);
}
GTEST_MAIN_RUN_ALL_TESTS()