forked from qt-creator/qt-creator
TaskTree: Introduce withTimeout()
Make it available for Group or CustomTask items. Note, that when withTimeout() is used, the total number of tasks grows by one. Change-Id: Idc71737ba66b92bdc4bf17599c793b1127d22f5e Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -567,6 +567,23 @@ void TaskItem::setTaskErrorHandler(const TaskEndHandler &handler)
|
|||||||
m_taskHandler.m_errorHandler = handler;
|
m_taskHandler.m_errorHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TaskItem TaskItem::withTimeout(const TaskItem &item, milliseconds timeout,
|
||||||
|
const GroupEndHandler &handler)
|
||||||
|
{
|
||||||
|
const TimeoutTask::EndHandler taskHandler = handler
|
||||||
|
? [handler](const milliseconds &) { handler(); } : TimeoutTask::EndHandler();
|
||||||
|
return Group {
|
||||||
|
parallel,
|
||||||
|
stopOnFinished,
|
||||||
|
Group {
|
||||||
|
finishAllAndError,
|
||||||
|
TimeoutTask([timeout](milliseconds &timeoutData) { timeoutData = timeout; },
|
||||||
|
taskHandler)
|
||||||
|
},
|
||||||
|
item
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class TaskTreePrivate;
|
class TaskTreePrivate;
|
||||||
class TaskNode;
|
class TaskNode;
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ protected:
|
|||||||
static TaskItem groupHandler(const GroupHandler &handler) { return TaskItem({handler}); }
|
static TaskItem groupHandler(const GroupHandler &handler) { return TaskItem({handler}); }
|
||||||
static TaskItem parallelLimit(int limit) { return TaskItem({{}, limit}); }
|
static TaskItem parallelLimit(int limit) { return TaskItem({{}, limit}); }
|
||||||
static TaskItem workflowPolicy(WorkflowPolicy policy) { return TaskItem({{}, {}, policy}); }
|
static TaskItem workflowPolicy(WorkflowPolicy policy) { return TaskItem({{}, {}, policy}); }
|
||||||
|
static TaskItem withTimeout(const TaskItem &item, std::chrono::milliseconds timeout,
|
||||||
|
const GroupEndHandler &handler = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type = Type::Group;
|
Type m_type = Type::Group;
|
||||||
@@ -216,6 +218,11 @@ public:
|
|||||||
using TaskItem::parallelLimit; // Default: 1 (sequential). 0 means unlimited (parallel).
|
using TaskItem::parallelLimit; // Default: 1 (sequential). 0 means unlimited (parallel).
|
||||||
using TaskItem::workflowPolicy; // Default: WorkflowPolicy::StopOnError.
|
using TaskItem::workflowPolicy; // Default: WorkflowPolicy::StopOnError.
|
||||||
|
|
||||||
|
TaskItem withTimeout(std::chrono::milliseconds timeout,
|
||||||
|
const GroupEndHandler &handler = {}) const {
|
||||||
|
return TaskItem::withTimeout(*this, timeout, handler);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename SetupHandler>
|
template<typename SetupHandler>
|
||||||
static GroupSetupHandler wrapGroupSetup(SetupHandler &&handler)
|
static GroupSetupHandler wrapGroupSetup(SetupHandler &&handler)
|
||||||
@@ -329,6 +336,11 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TaskItem withTimeout(std::chrono::milliseconds timeout,
|
||||||
|
const GroupEndHandler &handler = {}) const {
|
||||||
|
return TaskItem::withTimeout(*this, timeout, handler);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename SetupFunction>
|
template<typename SetupFunction>
|
||||||
static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
|
static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ enum class Handler {
|
|||||||
GroupDone,
|
GroupDone,
|
||||||
GroupError,
|
GroupError,
|
||||||
Sync,
|
Sync,
|
||||||
BarrierAdvance
|
BarrierAdvance,
|
||||||
|
Timeout
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(Handler);
|
Q_ENUM_NS(Handler);
|
||||||
|
|
||||||
@@ -245,6 +246,12 @@ void tst_Tasking::testTree_data()
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto setupTimeout = [storage](int taskId) {
|
||||||
|
return [storage, taskId] {
|
||||||
|
storage->m_log.append({taskId, Handler::Timeout});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const auto createTask = [storage, setupTask, setupDone, setupError](
|
const auto createTask = [storage, setupTask, setupDone, setupError](
|
||||||
int taskId, bool successTask, milliseconds timeout = 0ms) -> TaskItem {
|
int taskId, bool successTask, milliseconds timeout = 0ms) -> TaskItem {
|
||||||
if (successTask)
|
if (successTask)
|
||||||
@@ -2083,6 +2090,112 @@ void tst_Tasking::testTree_data()
|
|||||||
QTest::newRow("MultiBarrierParallelMultiWaitFor")
|
QTest::newRow("MultiBarrierParallelMultiWaitFor")
|
||||||
<< TestData{storage, root4, log4, 6, OnDone::Success};
|
<< TestData{storage, root4, log4, 6, OnDone::Success};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test CustomTask::withTimeout() combinations:
|
||||||
|
// 1. When the timeout has triggered or not.
|
||||||
|
// 2. With and without timeout handler.
|
||||||
|
const Group root1 {
|
||||||
|
Storage(storage),
|
||||||
|
TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1))
|
||||||
|
.withTimeout(1ms)
|
||||||
|
};
|
||||||
|
const Log log1 {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Error}
|
||||||
|
};
|
||||||
|
QTest::newRow("TaskErrorWithTimeout") << TestData{storage, root1, log1, 2,
|
||||||
|
OnDone::Failure};
|
||||||
|
|
||||||
|
const Group root2 {
|
||||||
|
Storage(storage),
|
||||||
|
TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1))
|
||||||
|
.withTimeout(1ms, setupTimeout(1))
|
||||||
|
};
|
||||||
|
const Log log2 {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Timeout},
|
||||||
|
{1, Handler::Error}
|
||||||
|
};
|
||||||
|
QTest::newRow("TaskErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2,
|
||||||
|
OnDone::Failure};
|
||||||
|
|
||||||
|
const Group root3 {
|
||||||
|
Storage(storage),
|
||||||
|
TestTask(setupTask(1, 1ms), setupDone(1), setupError(1))
|
||||||
|
.withTimeout(1000ms)
|
||||||
|
};
|
||||||
|
const Log doneLog {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Done}
|
||||||
|
};
|
||||||
|
QTest::newRow("TaskDoneWithTimeout") << TestData{storage, root3, doneLog, 2,
|
||||||
|
OnDone::Success};
|
||||||
|
|
||||||
|
const Group root4 {
|
||||||
|
Storage(storage),
|
||||||
|
TestTask(setupTask(1, 1ms), setupDone(1), setupError(1))
|
||||||
|
.withTimeout(1000ms, setupTimeout(1))
|
||||||
|
};
|
||||||
|
QTest::newRow("TaskDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2,
|
||||||
|
OnDone::Success};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test Group::withTimeout() combinations:
|
||||||
|
// 1. When the timeout has triggered or not.
|
||||||
|
// 2. With and without timeout handler.
|
||||||
|
const Group root1 {
|
||||||
|
Storage(storage),
|
||||||
|
Group {
|
||||||
|
createSuccessTask(1, 1000ms)
|
||||||
|
}.withTimeout(1ms)
|
||||||
|
};
|
||||||
|
const Log log1 {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Error}
|
||||||
|
};
|
||||||
|
QTest::newRow("GroupErrorWithTimeout") << TestData{storage, root1, log1, 2,
|
||||||
|
OnDone::Failure};
|
||||||
|
|
||||||
|
// Test Group::withTimeout(), passing custom handler
|
||||||
|
const Group root2 {
|
||||||
|
Storage(storage),
|
||||||
|
Group {
|
||||||
|
createSuccessTask(1, 1000ms)
|
||||||
|
}.withTimeout(1ms, setupTimeout(1))
|
||||||
|
};
|
||||||
|
const Log log2 {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Timeout},
|
||||||
|
{1, Handler::Error}
|
||||||
|
};
|
||||||
|
QTest::newRow("GroupErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2,
|
||||||
|
OnDone::Failure};
|
||||||
|
|
||||||
|
const Group root3 {
|
||||||
|
Storage(storage),
|
||||||
|
Group {
|
||||||
|
createSuccessTask(1, 1ms)
|
||||||
|
}.withTimeout(1000ms)
|
||||||
|
};
|
||||||
|
const Log doneLog {
|
||||||
|
{1, Handler::Setup},
|
||||||
|
{1, Handler::Done}
|
||||||
|
};
|
||||||
|
QTest::newRow("GroupDoneWithTimeout") << TestData{storage, root3, doneLog, 2,
|
||||||
|
OnDone::Success};
|
||||||
|
|
||||||
|
// Test Group::withTimeout(), passing custom handler
|
||||||
|
const Group root4 {
|
||||||
|
Storage(storage),
|
||||||
|
Group {
|
||||||
|
createSuccessTask(1, 1ms)
|
||||||
|
}.withTimeout(1000ms, setupTimeout(1))
|
||||||
|
};
|
||||||
|
QTest::newRow("GroupDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2,
|
||||||
|
OnDone::Success};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Tasking::testTree()
|
void tst_Tasking::testTree()
|
||||||
|
|||||||
Reference in New Issue
Block a user