mirror of
https://github.com/tnodir/fort
synced 2024-11-15 13:06:36 +00:00
UI: Straightforward RPC.
This commit is contained in:
parent
1c16d3b5d0
commit
21f302dbdf
@ -104,7 +104,6 @@ SOURCES += \
|
||||
task/taskworker.cpp \
|
||||
task/taskzonedownloader.cpp \
|
||||
translationmanager.cpp \
|
||||
util/classutil.cpp \
|
||||
util/conf/addressrange.cpp \
|
||||
util/conf/confutil.cpp \
|
||||
util/dateutil.cpp \
|
||||
@ -240,7 +239,6 @@ HEADERS += \
|
||||
task/taskzonedownloader.h \
|
||||
translationmanager.h \
|
||||
util/classhelpers.h \
|
||||
util/classutil.h \
|
||||
util/conf/addressrange.h \
|
||||
util/conf/confappswalker.h \
|
||||
util/conf/confutil.h \
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
namespace Control {
|
||||
|
||||
enum Command : qint8 { CommandNone = 0, CommandConf, CommandProg, CommandRpc };
|
||||
|
||||
enum RpcObject : qint8 {
|
||||
Rpc_None = 0,
|
||||
Rpc_AppInfoManager,
|
||||
Rpc_ConfManager,
|
||||
Rpc_DriverManager,
|
||||
Rpc_QuotaManager,
|
||||
Rpc_StatManager,
|
||||
Rpc_TaskManager,
|
||||
enum Command : qint8 {
|
||||
CommandNone = 0,
|
||||
Conf,
|
||||
Prog,
|
||||
Rpc_AppInfoManager_lookupAppInfo,
|
||||
Rpc_AppInfoManager_checkLookupFinished,
|
||||
Rpc_ConfManager_,
|
||||
Rpc_DriverManager_,
|
||||
Rpc_QuotaManager_alert,
|
||||
Rpc_StatManager_,
|
||||
Rpc_TaskManager_,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ bool ControlManager::postCommand()
|
||||
{
|
||||
Control::Command command;
|
||||
if (settings()->controlCommand() == "conf") {
|
||||
command = Control::CommandConf;
|
||||
command = Control::Conf;
|
||||
} else if (settings()->controlCommand() == "prog") {
|
||||
command = Control::CommandProg;
|
||||
command = Control::Prog;
|
||||
} else {
|
||||
logWarning() << "Unknown control command:" << settings()->controlCommand();
|
||||
return false;
|
||||
@ -91,7 +91,7 @@ bool ControlManager::postCommand()
|
||||
if (args.isEmpty())
|
||||
return false;
|
||||
|
||||
return worker.sendCommand(command, Control::Rpc_None, 0, args) && worker.waitForSent();
|
||||
return worker.sendCommand(command, args) && worker.waitForSent();
|
||||
}
|
||||
|
||||
void ControlManager::onNewConnection()
|
||||
@ -115,35 +115,31 @@ void ControlManager::onNewConnection()
|
||||
}
|
||||
}
|
||||
|
||||
bool ControlManager::processRequest(Control::Command command, Control::RpcObject rpcObj,
|
||||
qint16 methodIndex, const QVariantList &args)
|
||||
bool ControlManager::processRequest(Control::Command command, const QVariantList &args)
|
||||
{
|
||||
QString errorMessage;
|
||||
if (!processCommand(command, rpcObj, methodIndex, args, errorMessage)) {
|
||||
if (!processCommand(command, args, errorMessage)) {
|
||||
logWarning() << "Bad control command" << errorMessage << ':' << command << args;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ControlManager::processCommand(Control::Command command, Control::RpcObject rpcObj,
|
||||
qint16 methodIndex, const QVariantList &args, QString &errorMessage)
|
||||
bool ControlManager::processCommand(
|
||||
Control::Command command, const QVariantList &args, QString &errorMessage)
|
||||
{
|
||||
switch (command) {
|
||||
case Control::CommandConf:
|
||||
case Control::Conf:
|
||||
if (processCommandConf(args, errorMessage))
|
||||
return true;
|
||||
break;
|
||||
case Control::CommandProg:
|
||||
case Control::Prog:
|
||||
if (processCommandProg(args, errorMessage))
|
||||
return true;
|
||||
break;
|
||||
case Control::CommandRpc:
|
||||
if (rpcManager()->processCommandRpc(rpcObj, methodIndex, args, errorMessage))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
errorMessage = "Unknown command";
|
||||
if (rpcManager()->processCommandRpc(command, args, errorMessage))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (errorMessage.isEmpty()) {
|
||||
|
@ -36,17 +36,15 @@ public:
|
||||
bool postCommand();
|
||||
|
||||
signals:
|
||||
void rpcRequestReady(Control::RpcObject rpcObj, qint16 methodIndex, const QVariantList &args);
|
||||
void rpcRequestReady(Control::Command command, const QVariantList &args);
|
||||
|
||||
private slots:
|
||||
void onNewConnection();
|
||||
|
||||
bool processRequest(Control::Command command, Control::RpcObject rpcObj, qint16 methodIndex,
|
||||
const QVariantList &args);
|
||||
bool processRequest(Control::Command command, const QVariantList &args);
|
||||
|
||||
private:
|
||||
bool processCommand(Control::Command command, Control::RpcObject rpcObj, qint16 methodIndex,
|
||||
const QVariantList &args, QString &errorMessage);
|
||||
bool processCommand(Control::Command command, const QVariantList &args, QString &errorMessage);
|
||||
bool processCommandConf(const QVariantList &args, QString &errorMessage);
|
||||
bool processCommandProg(const QVariantList &args, QString &errorMessage);
|
||||
|
||||
|
@ -76,14 +76,13 @@ void ControlWorker::abort()
|
||||
socket()->close();
|
||||
}
|
||||
|
||||
bool ControlWorker::sendCommand(Control::Command command, Control::RpcObject rpcObj,
|
||||
int methodIndex, const QVariantList &args)
|
||||
bool ControlWorker::sendCommand(Control::Command command, const QVariantList &args)
|
||||
{
|
||||
QByteArray buffer;
|
||||
if (!buildArgsData(buffer, args))
|
||||
return false;
|
||||
|
||||
RequestHeader request(command, rpcObj, methodIndex, buffer.size());
|
||||
RequestHeader request(command, buffer.size());
|
||||
|
||||
socket()->write((const char *) &request, sizeof(RequestHeader));
|
||||
|
||||
@ -138,12 +137,10 @@ bool ControlWorker::readRequest()
|
||||
return false;
|
||||
|
||||
const Control::Command command = m_requestHeader.command();
|
||||
const Control::RpcObject rpcObj = m_requestHeader.rpcObj();
|
||||
const qint16 methodIndex = m_requestHeader.methodIndex();
|
||||
|
||||
clearRequest();
|
||||
|
||||
emit requestReady(command, rpcObj, methodIndex, args);
|
||||
emit requestReady(command, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -22,16 +22,14 @@ public:
|
||||
|
||||
void setupForAsync();
|
||||
|
||||
bool sendCommand(Control::Command command, Control::RpcObject rpcObj, int methodIndex,
|
||||
const QVariantList &args);
|
||||
bool sendCommand(Control::Command command, const QVariantList &args);
|
||||
|
||||
bool waitForSent(int msecs = 1000) const;
|
||||
|
||||
static QVariantList buildArgs(const QStringList &list);
|
||||
|
||||
signals:
|
||||
void requestReady(Control::Command command, Control::RpcObject rpcObj, qint16 methodIndex,
|
||||
const QVariantList &args);
|
||||
void requestReady(Control::Command command, const QVariantList &args);
|
||||
|
||||
public slots:
|
||||
void abort();
|
||||
@ -48,31 +46,23 @@ private:
|
||||
private:
|
||||
struct RequestHeader
|
||||
{
|
||||
RequestHeader(Control::Command command = Control::CommandNone,
|
||||
Control::RpcObject rpcObj = Control::Rpc_None, qint16 methodIndex = 0,
|
||||
quint32 dataSize = 0) :
|
||||
m_command(command), m_rpcObj(rpcObj), m_methodIndex(methodIndex), m_dataSize(dataSize)
|
||||
RequestHeader(Control::Command command = Control::CommandNone, quint32 dataSize = 0) :
|
||||
m_command(command), m_dataSize(dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
Control::Command command() const { return m_command; }
|
||||
Control::RpcObject rpcObj() const { return m_rpcObj; }
|
||||
qint16 methodIndex() const { return m_methodIndex; }
|
||||
Control::Command command() const { return static_cast<Control::Command>(m_command); }
|
||||
quint32 dataSize() const { return m_dataSize; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_command = Control::CommandNone;
|
||||
m_rpcObj = Control::Rpc_None;
|
||||
m_methodIndex = 0;
|
||||
m_dataSize = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Control::Command m_command;
|
||||
Control::RpcObject m_rpcObj;
|
||||
qint16 m_methodIndex;
|
||||
quint32 m_dataSize;
|
||||
quint32 m_command : 8;
|
||||
quint32 m_dataSize : 24;
|
||||
};
|
||||
|
||||
bool m_isServiceClient = false;
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "../fortmanager.h"
|
||||
#include "../rpc/rpcmanager.h"
|
||||
#include "../util/classutil.h"
|
||||
|
||||
AppInfoManagerRpc::AppInfoManagerRpc(
|
||||
const QString &filePath, FortManager *fortManager, QObject *parent) :
|
||||
@ -19,8 +18,7 @@ RpcManager *AppInfoManagerRpc::rpcManager() const
|
||||
|
||||
void AppInfoManagerRpc::lookupAppInfo(const QString &appPath)
|
||||
{
|
||||
static const int methodIndex = ClassUtil::indexOfMethod(&AppInfoManager::lookupAppInfo);
|
||||
rpcManager()->invokeOnServer(Control::Rpc_AppInfoManager, methodIndex, { appPath });
|
||||
rpcManager()->invokeOnServer(Control::Rpc_AppInfoManager_lookupAppInfo, { appPath });
|
||||
}
|
||||
|
||||
void AppInfoManagerRpc::updateAppAccessTime(const QString & /*appPath*/) { }
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "../rpc/quotamanagerrpc.h"
|
||||
#include "../rpc/statmanagerrpc.h"
|
||||
#include "../rpc/taskmanagerrpc.h"
|
||||
#include "../util/classutil.h"
|
||||
|
||||
RpcManager::RpcManager(FortManager *fortManager, QObject *parent) :
|
||||
QObject(parent), m_fortManager(fortManager)
|
||||
@ -27,6 +26,36 @@ ControlManager *RpcManager::controlManager() const
|
||||
return fortManager()->controlManager();
|
||||
}
|
||||
|
||||
AppInfoManager *RpcManager::appInfoManager() const
|
||||
{
|
||||
return fortManager()->appInfoManager();
|
||||
}
|
||||
|
||||
ConfManager *RpcManager::confManager() const
|
||||
{
|
||||
return fortManager()->confManager();
|
||||
}
|
||||
|
||||
DriverManager *RpcManager::driverManager() const
|
||||
{
|
||||
return fortManager()->driverManager();
|
||||
}
|
||||
|
||||
QuotaManager *RpcManager::quotaManager() const
|
||||
{
|
||||
return fortManager()->quotaManager();
|
||||
}
|
||||
|
||||
StatManager *RpcManager::statManager() const
|
||||
{
|
||||
return fortManager()->statManager();
|
||||
}
|
||||
|
||||
TaskManager *RpcManager::taskManager() const
|
||||
{
|
||||
return fortManager()->taskManager();
|
||||
}
|
||||
|
||||
void RpcManager::initialize()
|
||||
{
|
||||
if (settings()->isService()) {
|
||||
@ -34,18 +63,6 @@ void RpcManager::initialize()
|
||||
}
|
||||
}
|
||||
|
||||
bool RpcManager::processCommandRpc(
|
||||
Control::RpcObject rpcObj, int methodIndex, const QVariantList &args, QString &errorMessage)
|
||||
{
|
||||
QObject *o = getRpcObject(rpcObj);
|
||||
if (!o) {
|
||||
errorMessage = "Bad RPC: No object";
|
||||
return false;
|
||||
}
|
||||
|
||||
return ClassUtil::invokeMethod(o, methodIndex, args);
|
||||
}
|
||||
|
||||
void RpcManager::setupServerSignals()
|
||||
{
|
||||
setupAppInfoManagerSignals();
|
||||
@ -54,62 +71,62 @@ void RpcManager::setupServerSignals()
|
||||
|
||||
void RpcManager::setupAppInfoManagerSignals()
|
||||
{
|
||||
constexpr Control::RpcObject rpcObj = Control::Rpc_AppInfoManager;
|
||||
auto o = fortManager()->appInfoManager();
|
||||
|
||||
connect(o, &AppInfoManager::lookupFinished, this,
|
||||
connect(appInfoManager(), &AppInfoManager::lookupFinished, this,
|
||||
[&](const QString &appPath, const AppInfo & /*appInfo*/) {
|
||||
static const int methodIndex =
|
||||
ClassUtil::indexOfMethod(&AppInfoManager::checkLookupFinished);
|
||||
invokeOnClients(rpcObj, methodIndex, { appPath });
|
||||
invokeOnClients(Control::Rpc_AppInfoManager_checkLookupFinished, { appPath });
|
||||
});
|
||||
}
|
||||
|
||||
void RpcManager::setupQuotaManagerSignals()
|
||||
{
|
||||
constexpr Control::RpcObject rpcObj = Control::Rpc_QuotaManager;
|
||||
auto o = fortManager()->quotaManager();
|
||||
|
||||
connect(o, &QuotaManager::alert, this, [&](qint8 alertType) {
|
||||
static const int methodIndex = ClassUtil::indexOfSignal(&QuotaManager::alert);
|
||||
invokeOnClients(rpcObj, methodIndex, { alertType });
|
||||
connect(quotaManager(), &QuotaManager::alert, this, [&](qint8 alertType) {
|
||||
invokeOnClients(Control::Rpc_QuotaManager_alert, { alertType });
|
||||
});
|
||||
}
|
||||
|
||||
void RpcManager::invokeOnServer(
|
||||
Control::RpcObject rpcObj, int methodIndex, const QVariantList &args)
|
||||
void RpcManager::invokeOnServer(Control::Command cmd, const QVariantList &args)
|
||||
{
|
||||
m_client->sendCommand(Control::CommandRpc, rpcObj, methodIndex, args);
|
||||
m_client->sendCommand(cmd, args);
|
||||
}
|
||||
|
||||
void RpcManager::invokeOnClients(
|
||||
Control::RpcObject rpcObj, int methodIndex, const QVariantList &args)
|
||||
void RpcManager::invokeOnClients(Control::Command cmd, const QVariantList &args)
|
||||
{
|
||||
const auto clients = controlManager()->clients();
|
||||
for (ControlWorker *w : clients) {
|
||||
if (!w->isServiceClient())
|
||||
continue;
|
||||
|
||||
w->sendCommand(Control::CommandRpc, rpcObj, methodIndex, args);
|
||||
w->sendCommand(cmd, args);
|
||||
}
|
||||
}
|
||||
|
||||
QObject *RpcManager::getRpcObject(Control::RpcObject rpcObj) const
|
||||
bool RpcManager::processCommandRpc(
|
||||
Control::Command cmd, const QVariantList &args, QString &errorMessage)
|
||||
{
|
||||
switch (rpcObj) {
|
||||
case Control::Rpc_AppInfoManager:
|
||||
return fortManager()->appInfoManager();
|
||||
case Control::Rpc_ConfManager:
|
||||
return fortManager()->confManager();
|
||||
case Control::Rpc_DriverManager:
|
||||
return fortManager()->driverManager();
|
||||
case Control::Rpc_QuotaManager:
|
||||
return fortManager()->quotaManager();
|
||||
case Control::Rpc_StatManager:
|
||||
return fortManager()->statManager();
|
||||
case Control::Rpc_TaskManager:
|
||||
return fortManager()->taskManager();
|
||||
switch (cmd) {
|
||||
case Control::Rpc_AppInfoManager_lookupAppInfo:
|
||||
appInfoManager()->lookupAppInfo(args.value(0).toString());
|
||||
return true;
|
||||
case Control::Rpc_AppInfoManager_checkLookupFinished:
|
||||
appInfoManager()->checkLookupFinished(args.value(0).toString());
|
||||
return true;
|
||||
case Control::Rpc_ConfManager_:
|
||||
confManager();
|
||||
return true;
|
||||
case Control::Rpc_DriverManager_:
|
||||
driverManager();
|
||||
return true;
|
||||
case Control::Rpc_QuotaManager_alert:
|
||||
quotaManager();
|
||||
return true;
|
||||
case Control::Rpc_StatManager_:
|
||||
statManager();
|
||||
return true;
|
||||
case Control::Rpc_TaskManager_:
|
||||
taskManager();
|
||||
return true;
|
||||
default:
|
||||
return nullptr;
|
||||
errorMessage = "Unknown command";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,16 @@
|
||||
|
||||
#include "../control/control.h"
|
||||
|
||||
class AppInfoManager;
|
||||
class ConfManager;
|
||||
class ControlManager;
|
||||
class ControlWorker;
|
||||
class DriverManager;
|
||||
class FortManager;
|
||||
class FortSettings;
|
||||
class QuotaManager;
|
||||
class StatManager;
|
||||
class TaskManager;
|
||||
|
||||
class RpcManager : public QObject
|
||||
{
|
||||
@ -21,22 +27,25 @@ public:
|
||||
FortManager *fortManager() const { return m_fortManager; }
|
||||
FortSettings *settings() const;
|
||||
ControlManager *controlManager() const;
|
||||
AppInfoManager *appInfoManager() const;
|
||||
ConfManager *confManager() const;
|
||||
DriverManager *driverManager() const;
|
||||
QuotaManager *quotaManager() const;
|
||||
StatManager *statManager() const;
|
||||
TaskManager *taskManager() const;
|
||||
|
||||
void initialize();
|
||||
|
||||
bool processCommandRpc(Control::RpcObject rpcObj, int methodIndex, const QVariantList &args,
|
||||
QString &errorMessage);
|
||||
void invokeOnServer(Control::Command cmd, const QVariantList &args);
|
||||
|
||||
void invokeOnServer(Control::RpcObject rpcObj, int methodIndex, const QVariantList &args);
|
||||
bool processCommandRpc(Control::Command cmd, const QVariantList &args, QString &errorMessage);
|
||||
|
||||
private:
|
||||
void setupServerSignals();
|
||||
void setupAppInfoManagerSignals();
|
||||
void setupQuotaManagerSignals();
|
||||
|
||||
void invokeOnClients(Control::RpcObject rpcObj, int methodIndex, const QVariantList &args);
|
||||
|
||||
QObject *getRpcObject(Control::RpcObject rpcObj) const;
|
||||
void invokeOnClients(Control::Command cmd, const QVariantList &args);
|
||||
|
||||
private:
|
||||
FortManager *m_fortManager = nullptr;
|
||||
|
@ -1,38 +0,0 @@
|
||||
#include "classutil.h"
|
||||
|
||||
bool ClassUtil::invokeMethod(
|
||||
QObject *object, int methodIndex, const QVariantList &args, QVariant *result)
|
||||
{
|
||||
const QMetaMethod metaMethod = object->metaObject()->method(methodIndex);
|
||||
|
||||
constexpr int maxArgsCount = 5;
|
||||
Q_ASSERT(metaMethod.parameterTypes().size() == args.size() && args.size() <= maxArgsCount);
|
||||
|
||||
QVector<QGenericArgument> arguments(maxArgsCount);
|
||||
|
||||
for (const auto &arg : args) {
|
||||
void *data = const_cast<void *>(arg.constData()); // data() detaches it
|
||||
arguments.append(QGenericArgument(arg.typeName(), data));
|
||||
}
|
||||
|
||||
QVariant returnValue(metaMethod.returnMetaType(), nullptr);
|
||||
QGenericReturnArgument returnArgument(
|
||||
metaMethod.typeName(), const_cast<void *>(returnValue.constData()));
|
||||
|
||||
if (!metaMethod.invoke(object, Qt::DirectConnection, returnArgument, arguments.value(0),
|
||||
arguments.value(1), arguments.value(2), arguments.value(3), arguments.value(4)))
|
||||
return false;
|
||||
|
||||
if (result) {
|
||||
*result = returnValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int ClassUtil::getIndexOfMethod(const QMetaObject &metaObject, void **method)
|
||||
{
|
||||
int i = -1;
|
||||
void *args[] = { &i, method };
|
||||
metaObject.static_metacall(QMetaObject::IndexOfMethod, 0, args);
|
||||
return i;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
#ifndef CLASSUTIL_H
|
||||
#define CLASSUTIL_H
|
||||
|
||||
#include <QMetaMethod>
|
||||
#include <QVariant>
|
||||
|
||||
class ClassUtil
|
||||
{
|
||||
public:
|
||||
static bool invokeMethod(QObject *object, int methodIndex, const QVariantList &args = {},
|
||||
QVariant *result = nullptr);
|
||||
|
||||
template<typename PointerToMemberFunction>
|
||||
static int indexOfSignal(PointerToMemberFunction signal)
|
||||
{
|
||||
const QMetaMethod method = QMetaMethod::fromSignal(signal);
|
||||
return method.methodIndex();
|
||||
}
|
||||
|
||||
template<typename PointerToMemberFunction>
|
||||
static int indexOfMethod(PointerToMemberFunction method)
|
||||
{
|
||||
using MemberFunctionType = QtPrivate::FunctionPointer<PointerToMemberFunction>;
|
||||
return getIndexOfMethod(
|
||||
MemberFunctionType::Object::staticMetaObject, reinterpret_cast<void **>(&method));
|
||||
}
|
||||
|
||||
private:
|
||||
static int getIndexOfMethod(const QMetaObject &metaObject, void **method);
|
||||
};
|
||||
|
||||
#endif // CLASSUTIL_H
|
Loading…
Reference in New Issue
Block a user