TaskTree: Replace usages of Async with ConcurrentCall

The ConcurrentCall is more appropriate, since it's
a part of the Tasking solution.

Change-Id: I1a993a6afa552a7a6a26a450d4f23c15443fdfde
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
Jarek Kobus
2023-06-09 17:51:51 +02:00
parent 814fbd1c4f
commit 52fba04af5

View File

@@ -1123,7 +1123,7 @@ void TaskNode::invokeEndHandler(bool success)
Use the Tasking namespace to build extensible, declarative task tree Use the Tasking namespace to build extensible, declarative task tree
structures that contain possibly asynchronous tasks, such as Process, structures that contain possibly asynchronous tasks, such as Process,
FileTransfer, or Async<ReturnType>. TaskTree structures enable you FileTransfer, or ConcurrentCall<ReturnType>. TaskTree structures enable you
to create a sophisticated mixture of a parallel or sequential flow of tasks to create a sophisticated mixture of a parallel or sequential flow of tasks
in the form of a tree and to run it any time later. in the form of a tree and to run it any time later.
@@ -1131,14 +1131,14 @@ void TaskNode::invokeEndHandler(bool success)
The TaskTree has a mandatory Group root element, which may contain The TaskTree has a mandatory Group root element, which may contain
any number of tasks of various types, such as ProcessTask, FileTransferTask, any number of tasks of various types, such as ProcessTask, FileTransferTask,
or AsyncTask<ReturnType>: or ConcurrentCallTask<ReturnType>:
\code \code
using namespace Tasking; using namespace Tasking;
const Group root { const Group root {
ProcessTask(...), ProcessTask(...),
AsyncTask<int>(...), ConcurrentCallTask<int>(...),
FileTransferTask(...) FileTransferTask(...)
}; };
@@ -1149,10 +1149,10 @@ void TaskNode::invokeEndHandler(bool success)
\endcode \endcode
The task tree above has a top level element of the Group type that contains The task tree above has a top level element of the Group type that contains
tasks of the type ProcessTask, FileTransferTask, and AsyncTask<int>. tasks of the type ProcessTask, FileTransferTask, and ConcurrentCallTask<int>.
After taskTree->start() is called, the tasks are run in a chain, starting After taskTree->start() is called, the tasks are run in a chain, starting
with ProcessTask. When the ProcessTask finishes successfully, the AsyncTask<int> task is with ProcessTask. When the ProcessTask finishes successfully, the ConcurrentCallTask<int>
started. Finally, when the asynchronous task finishes successfully, the task is started. Finally, when the asynchronous task finishes successfully, the
FileTransferTask task is started. FileTransferTask task is started.
When the last running task finishes with success, the task tree is considered When the last running task finishes with success, the task tree is considered
@@ -1172,26 +1172,26 @@ void TaskNode::invokeEndHandler(bool success)
Group { Group {
parallel, parallel,
ProcessTask(...), ProcessTask(...),
AsyncTask<int>(...) ConcurrentCallTask<int>(...)
}, },
FileTransferTask(...) FileTransferTask(...)
}; };
\endcode \endcode
The example above differs from the first example in that the root element has The example above differs from the first example in that the root element has
a subgroup that contains the ProcessTask and AsyncTask<int>. The subgroup is a a subgroup that contains the ProcessTask and ConcurrentCallTask<int>. The subgroup is a
sibling element of the FileTransferTask in the root. The subgroup contains an sibling element of the FileTransferTask in the root. The subgroup contains an
additional \e parallel element that instructs its Group to execute its tasks additional \e parallel element that instructs its Group to execute its tasks
in parallel. in parallel.
So, when the tree above is started, the ProcessTask and AsyncTask<int> start So, when the tree above is started, the ProcessTask and ConcurrentCallTask<int> start
immediately and run in parallel. Since the root group doesn't contain a immediately and run in parallel. Since the root group doesn't contain a
\e parallel element, its direct child tasks are run in sequence. Thus, the \e parallel element, its direct child tasks are run in sequence. Thus, the
FileTransferTask starts when the whole subgroup finishes. The group is FileTransferTask starts when the whole subgroup finishes. The group is
considered as finished when all its tasks have finished. The order in which considered as finished when all its tasks have finished. The order in which
the tasks finish is not relevant. the tasks finish is not relevant.
So, depending on which task lasts longer (ProcessTask or AsyncTask<int>), the So, depending on which task lasts longer (ProcessTask or ConcurrentCallTask<int>), the
following scenarios can take place: following scenarios can take place:
\table \table
@@ -1208,19 +1208,19 @@ void TaskNode::invokeEndHandler(bool success)
\li ProcessTask starts \li ProcessTask starts
\li ProcessTask starts \li ProcessTask starts
\row \row
\li AsyncTask<int> starts \li ConcurrentCallTask<int> starts
\li AsyncTask<int> starts \li ConcurrentCallTask<int> starts
\row \row
\li ... \li ...
\li ... \li ...
\row \row
\li \b {ProcessTask finishes} \li \b {ProcessTask finishes}
\li \b {AsyncTask<int> finishes} \li \b {ConcurrentCallTask<int> finishes}
\row \row
\li ... \li ...
\li ... \li ...
\row \row
\li \b {AsyncTask<int> finishes} \li \b {ConcurrentCallTask<int> finishes}
\li \b {ProcessTask finishes} \li \b {ProcessTask finishes}
\row \row
\li Sub Group finishes \li Sub Group finishes
@@ -1246,8 +1246,8 @@ void TaskNode::invokeEndHandler(bool success)
The presented scenarios assume that all tasks run successfully. If a task The presented scenarios assume that all tasks run successfully. If a task
fails during execution, the task tree finishes with an error. In particular, fails during execution, the task tree finishes with an error. In particular,
when ProcessTask finishes with an error while AsyncTask<int> is still being executed, when ProcessTask finishes with an error while ConcurrentCallTask<int> is still being executed,
the AsyncTask<int> is automatically stopped, the subgroup finishes with an error, the ConcurrentCallTask<int> is automatically stopped, the subgroup finishes with an error,
the FileTransferTask is skipped, and the tree finishes with an error. the FileTransferTask is skipped, and the tree finishes with an error.
\section1 Task Types \section1 Task Types
@@ -1277,11 +1277,11 @@ void TaskNode::invokeEndHandler(bool success)
\row \row
\li ProcessTask \li ProcessTask
\li Utils::Process \li Utils::Process
\li Starts processes. \li Starts process.
\row \row
\li AsyncTask<ReturnType> \li ConcurrentCallTask<ReturnType>
\li Utils::Async<ReturnType> \li Tasking::ConcurrentCall<ReturnType>
\li Starts asynchronous tasks; run in separate thread. \li Starts asynchronous task, runs in separate thread.
\row \row
\li TaskTreeTask \li TaskTreeTask
\li Utils::TaskTree \li Utils::TaskTree
@@ -1549,28 +1549,28 @@ void TaskNode::invokeEndHandler(bool success)
// [3] instance of custom inter-task struct manageable by task tree // [3] instance of custom inter-task struct manageable by task tree
const TreeStorage<CopyStorage> storage; const TreeStorage<CopyStorage> storage;
const auto onLoaderSetup = [source](Async<QByteArray> &async) { const auto onLoaderSetup = [source](ConcurrentCall<QByteArray> &async) {
async.setConcurrentCallData(&load, source); async.setConcurrentCallData(&load, source);
}; };
// [4] runtime: task tree activates the instance from [7] before invoking handler // [4] runtime: task tree activates the instance from [7] before invoking handler
const auto onLoaderDone = [storage](const Async<QByteArray> &async) { const auto onLoaderDone = [storage](const ConcurrentCall<QByteArray> &async) {
storage->content = async.result(); // [5] loader stores the result in storage storage->content = async.result(); // [5] loader stores the result in storage
}; };
// [4] runtime: task tree activates the instance from [7] before invoking handler // [4] runtime: task tree activates the instance from [7] before invoking handler
const auto onSaverSetup = [storage, destination](Async<void> &async) { const auto onSaverSetup = [storage, destination](ConcurrentCall<void> &async) {
const QByteArray content = storage->content; // [6] saver takes data from storage const QByteArray content = storage->content; // [6] saver takes data from storage
async.setConcurrentCallData(&save, destination, content); async.setConcurrentCallData(&save, destination, content);
}; };
const auto onSaverDone = [](const Async<void> &async) { const auto onSaverDone = [](const ConcurrentCall<void> &async) {
qDebug() << "Save done successfully"; qDebug() << "Save done successfully";
}; };
const Group root { const Group root {
// [7] runtime: task tree creates an instance of CopyStorage when root is entered // [7] runtime: task tree creates an instance of CopyStorage when root is entered
Storage(storage), Storage(storage),
AsyncTask<QByteArray>(onLoaderSetup, onLoaderDone), ConcurrentCallTask<QByteArray>(onLoaderSetup, onLoaderDone),
AsyncTask<void>(onSaverSetup, onSaverDone) ConcurrentCallTask<void>(onSaverSetup, onSaverDone)
}; };
return root; return root;
} }