mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
Implement make_cancelling_continuable()
* Can be used to cancel the chain when being inside a handler
This commit is contained in:
parent
4127c02c3f
commit
f469b7058a
@ -360,10 +360,11 @@ public:
|
||||
/// \since 2.0.0
|
||||
template <typename OData, typename OAnnotation>
|
||||
auto fail(continuable_base<OData, OAnnotation>&& continuation) && {
|
||||
return std::move(*this).fail(
|
||||
[continuation = std::move(continuation).freeze()](exception_t) mutable {
|
||||
std::move(continuation).done();
|
||||
});
|
||||
return std::move(*this) //
|
||||
.fail([continuation = std::move(continuation).freeze()] //
|
||||
(exception_t) mutable {
|
||||
std::move(continuation).done(); //
|
||||
});
|
||||
}
|
||||
|
||||
/// A method which allows to use an overloaded callable for the error
|
||||
@ -866,6 +867,35 @@ constexpr auto make_exceptional_continuable(Exception&& exception) {
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a continuable_base with the parameterized result which never
|
||||
/// resolves its promise and thus cancels the asynchronous continuation chain.
|
||||
///
|
||||
/// This can be used to cancel an asynchronous continuation chain when
|
||||
/// returning a continuable_base from a handler where other paths could
|
||||
/// possibly continue the asynchronous chain. See an example below:
|
||||
/// ```cpp
|
||||
/// do_sth().then([weak = this->weak_from_this()]() -> continuable<> {
|
||||
/// if (auto me = weak.lock()) {
|
||||
/// return do_sth_more();
|
||||
/// } else {
|
||||
/// // Abort the asynchronous continuation chain since the
|
||||
/// // weakly referenced object expired previously.
|
||||
/// return make_cancelling_continuable<void>();
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// \tparam Signature The fake signature of the returned continuable.
|
||||
///
|
||||
/// \since 4.0.0
|
||||
template <typename... Signature>
|
||||
auto make_cancelling_continuable() {
|
||||
static_assert(sizeof...(Signature) > 0,
|
||||
"Requires at least one type for the fake signature!");
|
||||
|
||||
return make_continuable<Signature...>([](auto&&) { /* ... */ });
|
||||
}
|
||||
|
||||
/// Can be used to recover to from a failure handler,
|
||||
/// the result handler which comes after will be called with the
|
||||
/// corresponding result.
|
||||
|
||||
@ -45,7 +45,8 @@ TYPED_TEST(single_dimension_tests, are_called_on_destruct) {
|
||||
ASSERT_ASYNC_TYPES(this->supply(tag1{}), tag1);
|
||||
}
|
||||
|
||||
template <typename T> auto create_incomplete(T* me) {
|
||||
template <typename T>
|
||||
auto create_incomplete(T* me) {
|
||||
return me->make(identity<>{}, identity<void>{}, [](auto&& callback) mutable {
|
||||
// Destruct the callback here
|
||||
auto destroy = std::forward<decltype(callback)>(callback);
|
||||
@ -53,7 +54,16 @@ template <typename T> auto create_incomplete(T* me) {
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T> auto assert_invocation(T* me) {
|
||||
template <typename T>
|
||||
auto create_incomplete_cancelling(T* me) {
|
||||
return me->make(identity<>{}, identity<void>{}, [](auto&& callback) mutable {
|
||||
make_cancelling_continuable<void>().next(
|
||||
std::forward<decltype(callback)>(callback));
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto assert_invocation(T* me) {
|
||||
return me->make(identity<>{}, identity<void>{},
|
||||
[](auto&& /*callback*/) mutable { FAIL(); });
|
||||
}
|
||||
@ -90,6 +100,18 @@ TYPED_TEST(single_dimension_tests, are_not_finished_when_not_continued) {
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_not_finished_when_cancelling) {
|
||||
{
|
||||
auto chain = create_incomplete_cancelling(this);
|
||||
ASSERT_ASYNC_INCOMPLETION(std::move(chain));
|
||||
}
|
||||
|
||||
{
|
||||
auto chain = create_incomplete_cancelling(this);
|
||||
ASSERT_ASYNC_INCOMPLETION(std::move(chain).then(this->supply()));
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, freeze_is_kept_across_the_chain) {
|
||||
{
|
||||
auto chain = this->supply().freeze().then([=] { return this->supply(); });
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user