feat: Repeating operations for util::async (#1776)

Async framework needed a way to do repeating operations (think simplest
cases like AmendmentBlockHandler).
This PR implements the **absolute minimum**, barebones repeating
operations that
- Can't return any values (void)
- Do not take any arguments in the user-provided function
- Can't be scheduled (i.e. a delay before starting repeating)
- Can't be stopped from inside the user block of code (i.e. does not
have stop token or anything like that)
- Can be stopped through the RepeatedOperation's `abort()` function (but
not from the user-provided repeating function)
This commit is contained in:
Alex Kremer
2024-12-20 13:24:01 +00:00
committed by GitHub
parent f2a89b095d
commit 285d4e6e9b
17 changed files with 292 additions and 90 deletions

View File

@@ -36,15 +36,18 @@ struct AnyOperationTests : Test {
using OperationType = MockOperation<std::expected<std::any, ExecutionError>>;
using StoppableOperationType = MockStoppableOperation<std::expected<std::any, ExecutionError>>;
using ScheduledOperationType = MockScheduledOperation<std::expected<std::any, ExecutionError>>;
using RepeatingOperationType = MockRepeatingOperation<std::expected<std::any, ExecutionError>>;
NaggyMock<OperationType> mockOp;
NaggyMock<StoppableOperationType> mockStoppableOp;
NaggyMock<ScheduledOperationType> mockScheduledOp;
NaggyMock<RepeatingOperationType> mockRepeatingOp;
AnyOperation<void> voidOp{impl::ErasedOperation(static_cast<OperationType&>(mockOp))};
AnyOperation<void> voidStoppableOp{impl::ErasedOperation(static_cast<StoppableOperationType&>(mockStoppableOp))};
AnyOperation<int> intOp{impl::ErasedOperation(static_cast<OperationType&>(mockOp))};
AnyOperation<void> scheduledVoidOp{impl::ErasedOperation(static_cast<ScheduledOperationType&>(mockScheduledOp))};
AnyOperation<void> repeatingOp{impl::ErasedOperation(static_cast<RepeatingOperationType&>(mockRepeatingOp))};
};
using AnyOperationDeathTest = AnyOperationTests;
@@ -113,6 +116,18 @@ TEST_F(AnyOperationTests, GetIncorrectDataReturnsError)
EXPECT_TRUE(std::string{res.error()}.ends_with("Bad any cast"));
}
TEST_F(AnyOperationTests, RepeatingOpWaitPropagated)
{
EXPECT_CALL(mockRepeatingOp, wait());
repeatingOp.wait();
}
TEST_F(AnyOperationTests, RepeatingOpRequestStopCallPropagated)
{
EXPECT_CALL(mockRepeatingOp, requestStop());
repeatingOp.abort();
}
TEST_F(AnyOperationDeathTest, CallAbortOnNonStoppableOrCancellableOperation)
{
EXPECT_DEATH(voidOp.abort(), ".*");