feat: finish dbus service: job/jobManager
Log:
This commit is contained in:
parent
3a278bec79
commit
d288752fb3
@ -13,7 +13,7 @@ set(CMAKE_AUTORCC ON)
|
|||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core DBus)
|
find_package(Qt6 REQUIRED COMPONENTS Core DBus Concurrent)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
value="Value of `Status` is one of
|
value="Value of `Status` is one of
|
||||||
`started`, `running`, `finished`,
|
`started`, `running`, `finished`,
|
||||||
`suspending`, `suspend`,
|
`suspending`, `suspend`,
|
||||||
`canceled` and `failed`."
|
`canceled`."
|
||||||
/>
|
/>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
@ -22,13 +22,13 @@
|
|||||||
will be emitted."
|
will be emitted."
|
||||||
/>
|
/>
|
||||||
</method>
|
</method>
|
||||||
<method name="Pause">
|
<method name="Suspend">
|
||||||
<annotation
|
<annotation
|
||||||
name="org.freedesktop.DBus.Description"
|
name="org.freedesktop.DBus.Description"
|
||||||
value="Success call to this method will
|
value="Success call to this method will
|
||||||
change the Status of this Job to `pausing`.
|
change the Status of this Job to `suspending`.
|
||||||
Then after some time this method call return,
|
Then after some time this method call return,
|
||||||
Status will change to `paused`."
|
Status will change to `suspend`."
|
||||||
/>
|
/>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
@ -36,8 +36,7 @@
|
|||||||
<annotation
|
<annotation
|
||||||
name="org.freedesktop.DBus.Description"
|
name="org.freedesktop.DBus.Description"
|
||||||
value="Success call to this method will
|
value="Success call to this method will
|
||||||
change the Status of this Job to `resuming`.
|
Resumes the asynchronous computation.
|
||||||
Resuming Jobs will be queued along with pending Jobs.
|
|
||||||
Then after some time this method call return,
|
Then after some time this method call return,
|
||||||
Status will change to `working`."
|
Status will change to `working`."
|
||||||
/>
|
/>
|
||||||
|
@ -26,17 +26,16 @@
|
|||||||
<signal name="JobRemoved">
|
<signal name="JobRemoved">
|
||||||
<arg type="o" name="job" />
|
<arg type="o" name="job" />
|
||||||
<arg type="s" name="status" />
|
<arg type="s" name="status" />
|
||||||
<arg type="s" name="message" />
|
<arg type="av" name="result" />
|
||||||
<arg type="v" name="result" />
|
|
||||||
|
|
||||||
<annotation
|
<annotation
|
||||||
name="org.freedesktop.DBus.Description"
|
name="org.freedesktop.DBus.Description"
|
||||||
value="This signal report the job remove event.
|
value="This signal report the job remove event.
|
||||||
`status` is the `status` porperty of that Job
|
`status` is the `status` porperty of that Job
|
||||||
when it got removed.
|
when it got removed.
|
||||||
`message` is the human readable message
|
`result` is the result which produce by this job,
|
||||||
for caller to report to user or just simple logging.
|
and user needs to traverse the list to determine
|
||||||
`result` is the result this job produce if it success.
|
if the values are valid or not.
|
||||||
Method that return an object of Job
|
Method that return an object of Job
|
||||||
should always have document
|
should always have document
|
||||||
about the type and meaning of the `result`."
|
about the type and meaning of the `result`."
|
||||||
|
@ -24,6 +24,7 @@ target_include_directories(${BIN_NAME} PRIVATE
|
|||||||
target_link_libraries(${BIN_NAME} PRIVATE
|
target_link_libraries(${BIN_NAME} PRIVATE
|
||||||
Qt${QT_VERSION_MAJOR}::Core
|
Qt${QT_VERSION_MAJOR}::Core
|
||||||
Qt${QT_VERSION_MAJOR}::DBus
|
Qt${QT_VERSION_MAJOR}::DBus
|
||||||
|
Qt${QT_VERSION_MAJOR}::Concurrent
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,24 +3,7 @@
|
|||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
#include "jobmanager1service.h"
|
#include "jobmanager1service.h"
|
||||||
#include <QUuid>
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
JobManager1Service::JobManager1Service() = default;
|
JobManager1Service::JobManager1Service() = default;
|
||||||
|
|
||||||
JobManager1Service::~JobManager1Service() = default;
|
JobManager1Service::~JobManager1Service() = default;
|
||||||
|
|
||||||
template <typename F, typename... Args>
|
|
||||||
void addJob(const QDBusObjectPath &source, F func, Args &&...args)
|
|
||||||
{
|
|
||||||
// TODO: impl
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JobManager1Service::removeJob(const QDBusObjectPath &job,
|
|
||||||
const QString &status,
|
|
||||||
const QString &message,
|
|
||||||
const QDBusVariant &result)
|
|
||||||
{
|
|
||||||
// TODO: impl
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,14 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QDBusObjectPath>
|
#include <QDBusObjectPath>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include "jobservice.h"
|
#include <QMutex>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QUuid>
|
||||||
|
#include "jobadaptor.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
class JobManager1Service final : public QObject
|
class JobManager1Service final : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -21,15 +28,52 @@ public:
|
|||||||
JobManager1Service &operator=(JobManager1Service &&) = delete;
|
JobManager1Service &operator=(JobManager1Service &&) = delete;
|
||||||
|
|
||||||
~JobManager1Service() override;
|
~JobManager1Service() override;
|
||||||
template<typename F,typename ...Args>
|
template <typename F>
|
||||||
void addJob(const QDBusObjectPath &source,F func, Args&& ...args);
|
void addJob(const QDBusObjectPath &source, F func, QVariantList args)
|
||||||
bool removeJob(const QDBusObjectPath &job, const QString &status, const QString &message, const QDBusVariant &result);
|
{
|
||||||
|
static_assert(std::is_invocable_v<F, QVariant>, "param type must be QVariant.");
|
||||||
|
|
||||||
|
QString objectPath{DDEApplicationManager1JobObjectPath + QUuid::createUuid().toString()};
|
||||||
|
QFuture<QVariantList> future = QtConcurrent::mappedReduced(
|
||||||
|
args.begin(), args.end(), func, &QVariantList::insert, QVariantList{}, QtConcurrent::ReduceOption::OrderedReduce);
|
||||||
|
QSharedPointer<JobService> job{new JobService{future}};
|
||||||
|
auto path = QDBusObjectPath{objectPath};
|
||||||
|
{
|
||||||
|
QMutexLocker locker{&m_mutex};
|
||||||
|
m_jobs.insert(path, job); // Insertion is always successful
|
||||||
|
}
|
||||||
|
emit JobNew(path, source);
|
||||||
|
registerObjectToDbus<decltype(job.data()), JobAdaptor>(job.data(), objectPath, getDBusInterface<JobAdaptor>());
|
||||||
|
auto emitRemove = [this, job, path, future] {
|
||||||
|
decltype(m_jobs)::size_type removeCount{0};
|
||||||
|
{
|
||||||
|
QMutexLocker locker{&m_mutex};
|
||||||
|
removeCount = m_jobs.remove(path);
|
||||||
|
}
|
||||||
|
// removeCount means m_jobs can't find value which corresponding with path
|
||||||
|
// and we shouldn't emit jobRemoved signal because this signal may already has been emit
|
||||||
|
if (removeCount == 0) {
|
||||||
|
qCritical() << "Job already has been removed: " << path.path();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString result{job->status()};
|
||||||
|
for (const auto &val : future.result()) {
|
||||||
|
if (val.canConvert<QDBusError>()) {
|
||||||
|
result = "failed";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit this->JobRemoved(path, result, future.result());
|
||||||
|
};
|
||||||
|
future.then(QtFuture::Launch::Sync, emitRemove);
|
||||||
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void JobNew(const QDBusObjectPath &job, const QDBusObjectPath &source);
|
void JobNew(const QDBusObjectPath &job, const QDBusObjectPath &source);
|
||||||
void JobRemoved(const QDBusObjectPath &job, const QString &status, const QString &message, const QDBusVariant &result);
|
void JobRemoved(const QDBusObjectPath &job, const QString &status, const QVariantList &result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QMutex m_mutex;
|
||||||
QMap<QDBusObjectPath, QSharedPointer<JobService>> m_jobs;
|
QMap<QDBusObjectPath, QSharedPointer<JobService>> m_jobs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "jobservice.h"
|
#include "jobservice.h"
|
||||||
|
|
||||||
JobService::JobService(const QFuture<QVariant>& job)
|
JobService::JobService(const QFuture<QVariantList>& job)
|
||||||
: m_job(job)
|
: m_job(job)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ QString JobService::status() const
|
|||||||
if (m_job.isRunning()) {
|
if (m_job.isRunning()) {
|
||||||
return "running";
|
return "running";
|
||||||
}
|
}
|
||||||
return "failed";
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JobService::Cancel()
|
void JobService::Cancel()
|
||||||
@ -39,7 +39,7 @@ void JobService::Cancel()
|
|||||||
m_job.cancel();
|
m_job.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JobService::Pause()
|
void JobService::Suspend()
|
||||||
{
|
{
|
||||||
m_job.suspend();
|
m_job.suspend();
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,23 @@ class JobService : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
~JobService() override;
|
~JobService() override;
|
||||||
|
JobService(const JobService &) = delete;
|
||||||
|
JobService(JobService &&) = delete;
|
||||||
|
JobService &operator=(const JobService &) = delete;
|
||||||
|
JobService &operator=(JobService &&) = delete;
|
||||||
|
|
||||||
Q_PROPERTY(QString Status READ status)
|
Q_PROPERTY(QString Status READ status)
|
||||||
QString status() const;
|
QString status() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void Cancel();
|
void Cancel();
|
||||||
void Pause();
|
void Suspend();
|
||||||
void Resume();
|
void Resume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit JobService(const QFuture<QVariant>& job);
|
friend class JobManager1Service;
|
||||||
QFuture<QVariant> m_job;
|
explicit JobService(const QFuture<QVariantList>& job);
|
||||||
|
QFuture<QVariantList> m_job;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,7 +62,7 @@ bool registerObjectToDbus(T parent, const QString &path, const QString &interfac
|
|||||||
"param type must derive QObject");
|
"param type must derive QObject");
|
||||||
auto &con = ApplicationManager1DBus::instance().CustomBus();
|
auto &con = ApplicationManager1DBus::instance().CustomBus();
|
||||||
if (!con.registerObject(path, interface, new U{parent})) {
|
if (!con.registerObject(path, interface, new U{parent})) {
|
||||||
qWarning() << "register object failed:" << path << interface << con.lastError();
|
qCritical() << "register object failed:" << path << interface << con.lastError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user