From df174f9813ae1a66b7b027ae94e666cdb09d50ae Mon Sep 17 00:00:00 2001 From: Arttu Tarkiainen Date: Mon, 2 May 2022 18:21:13 +0300 Subject: Add more generic trace messages for concurrent operations This makes the output more consistent between operations in Unpack and Install phase and removes the need to hard code some print to the operation side. Change-Id: Ia955f479cb138fcf0ffd6a73a06de6a74df6ed13 Reviewed-by: Katja Marttila --- doc/includes/IFWDoc | 1 + src/libs/installer/concurrentoperationrunner.cpp | 84 +++++++++---- src/libs/installer/concurrentoperationrunner.h | 3 + src/libs/installer/extractarchiveoperation.cpp | 1 - src/libs/installer/installer.pro | 4 +- src/libs/installer/operationtracer.cpp | 151 +++++++++++++++++++++++ src/libs/installer/operationtracer.h | 68 ++++++++++ src/libs/installer/packagemanagercore_p.cpp | 41 +----- src/libs/installer/packagemanagercore_p.h | 2 +- src/libs/kdtools/updateoperation.cpp | 2 + src/libs/kdtools/updateoperation.h | 2 + 11 files changed, 298 insertions(+), 61 deletions(-) create mode 100644 src/libs/installer/operationtracer.cpp create mode 100644 src/libs/installer/operationtracer.h diff --git a/doc/includes/IFWDoc b/doc/includes/IFWDoc index 936a6812e..fd86176ea 100644 --- a/doc/includes/IFWDoc +++ b/doc/includes/IFWDoc @@ -59,6 +59,7 @@ #include "metadatajob.h" #include "minimumprogressoperation.h" #include "observer.h" +#include "operationtracer.h" #include "packagemanagercoredata.h" #include "packagemanagercore.h" #include "packagemanagergui.h" diff --git a/src/libs/installer/concurrentoperationrunner.cpp b/src/libs/installer/concurrentoperationrunner.cpp index 403fb2b4e..dfcae44dd 100644 --- a/src/libs/installer/concurrentoperationrunner.cpp +++ b/src/libs/installer/concurrentoperationrunner.cpp @@ -29,6 +29,7 @@ #include "concurrentoperationrunner.h" #include "errors.h" +#include "operationtracer.h" #include @@ -47,6 +48,12 @@ using namespace QInstaller; system. */ +/*! + \fn QInstaller::ConcurrentOperationRunner::operationStarted(QInstaller::Operation *operation) + + Emitted when the execution of \a operation is started. +*/ + /*! \fn QInstaller::ConcurrentOperationRunner::finished() @@ -70,6 +77,8 @@ ConcurrentOperationRunner::ConcurrentOperationRunner(QObject *parent) , m_type(Operation::OperationType::Perform) , m_threadPool(new QThreadPool(this)) { + connect(this, &ConcurrentOperationRunner::operationStarted, + this, &ConcurrentOperationRunner::onOperationStarted); } /*! @@ -86,6 +95,9 @@ ConcurrentOperationRunner::ConcurrentOperationRunner(OperationList *operations, , m_threadPool(new QThreadPool(this)) { m_totalOperations = m_operations->size(); + + connect(this, &ConcurrentOperationRunner::operationStarted, + this, &ConcurrentOperationRunner::onOperationStarted); } /*! @@ -127,27 +139,6 @@ void ConcurrentOperationRunner::setMaxThreadCount(int count) m_threadPool->setMaxThreadCount(count); } -/*! - \internal - - Runs \a operation in mode of \a type. Returns \c true on success, \c false otherwise. -*/ -static bool runOperation(Operation *const operation, const Operation::OperationType type) -{ - switch (type) { - case Operation::Backup: - operation->backup(); - return true; - case Operation::Perform: - return operation->performOperation(); - case Operation::Undo: - return operation->undoOperation(); - default: - Q_ASSERT(!"Unexpected operation type"); - } - return false; -} - /*! Performs the current operations. Returns a hash of pointers to the performed operation objects and their results. The result is a boolean value. @@ -164,7 +155,8 @@ QHash ConcurrentOperationRunner::run() connect(futureWatcher, &QFutureWatcher::finished, this, &ConcurrentOperationRunner::onOperationfinished); - futureWatcher->setFuture(QtConcurrent::run(m_threadPool, &runOperation, operation, m_type)); + futureWatcher->setFuture(QtConcurrent::run(m_threadPool, + this, &ConcurrentOperationRunner::runOperation, operation)); } if (!m_operationWatchers.isEmpty()) { @@ -187,6 +179,31 @@ void ConcurrentOperationRunner::cancel() watcher->cancel(); } +/*! + \internal + + Invoked when the execution of the \a operation has started. Adds console + output trace for the operation. +*/ +void ConcurrentOperationRunner::onOperationStarted(Operation *operation) +{ + ConcurrentOperationTracer tracer(operation); + + switch (m_type) { + case Operation::Backup: + tracer.trace(QLatin1String("backup")); + break; + case Operation::Perform: + tracer.trace(QLatin1String("perform")); + break; + case Operation::Undo: + tracer.trace(QLatin1String("undo")); + break; + default: + Q_ASSERT(!"Unexpected operation type"); + } +} + /*! \internal @@ -224,6 +241,29 @@ void ConcurrentOperationRunner::onOperationfinished() emit finished(); } +/*! + \internal + + Runs \a operation. Returns \c true on success, \c false otherwise. +*/ +bool ConcurrentOperationRunner::runOperation(Operation *const operation) +{ + emit operationStarted(operation); + + switch (m_type) { + case Operation::Backup: + operation->backup(); + return true; + case Operation::Perform: + return operation->performOperation(); + case Operation::Undo: + return operation->undoOperation(); + default: + Q_ASSERT(!"Unexpected operation type"); + } + return false; +} + /*! \internal diff --git a/src/libs/installer/concurrentoperationrunner.h b/src/libs/installer/concurrentoperationrunner.h index f30020a95..436a2baef 100644 --- a/src/libs/installer/concurrentoperationrunner.h +++ b/src/libs/installer/concurrentoperationrunner.h @@ -55,6 +55,7 @@ public: QHash run(); signals: + void operationStarted(QInstaller::Operation *operation); void progressChanged(const int completed, const int total); void finished(); @@ -62,9 +63,11 @@ public slots: void cancel(); private slots: + void onOperationStarted(QInstaller::Operation *operation); void onOperationfinished(); private: + bool runOperation(Operation *const operation); void reset(); private: diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp index 5dbb49454..5ff2d9a1a 100644 --- a/src/libs/installer/extractarchiveoperation.cpp +++ b/src/libs/installer/extractarchiveoperation.cpp @@ -148,7 +148,6 @@ bool ExtractArchiveOperation::performOperation() connect(core, &PackageManagerCore::statusChanged, worker, &Worker::onStatusChanged); QFileInfo fileInfo(archivePath); - qCDebug(lcInstallerInstallLog) << "Extracting" << fileInfo.fileName(); emit outputTextChanged(tr("Extracting \"%1\"").arg(fileInfo.fileName())); { QEventLoop loop; diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro index fca960bec..6eebed33b 100644 --- a/src/libs/installer/installer.pro +++ b/src/libs/installer/installer.pro @@ -137,7 +137,8 @@ HEADERS += packagemanagercore.h \ commandlineparser_p.h \ abstractarchive.h \ directoryguard.h \ - archivefactory.h + archivefactory.h \ + operationtracer.h SOURCES += packagemanagercore.cpp \ abstractarchive.cpp \ @@ -148,6 +149,7 @@ SOURCES += packagemanagercore.cpp \ fileguard.cpp \ componentsortfilterproxymodel.cpp \ loggingutils.cpp \ + operationtracer.cpp \ packagemanagercore_p.cpp \ packagemanagergui.cpp \ binaryformat.cpp \ diff --git a/src/libs/installer/operationtracer.cpp b/src/libs/installer/operationtracer.cpp new file mode 100644 index 000000000..b09c08d2e --- /dev/null +++ b/src/libs/installer/operationtracer.cpp @@ -0,0 +1,151 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "operationtracer.h" + +#include "packagemanagercore.h" + +namespace QInstaller { + +/*! + \inmodule QtInstallerFramework + \class QInstaller::AbstractOperationTracer + \brief The AbstractOperationTracer is a pure virtual base class for classes + tracing starting and finishing of installer operations. +*/ + +/*! + \fn QInstaller::AbstractOperationTracer::~AbstractOperationTracer() + + Destructs object. A subclass may override this method. +*/ + +/*! + \fn QInstaller::AbstractOperationTracer::trace(const QString &state) + + Prints trace output for starting operation in \a state. + A subclass should implement this method. +*/ + +/*! + Constructs tracer for \a operation. Objects of this class cannot + be constructed directly, but the derived classes should explicitly call + the base class constructor in their constructors. +*/ +AbstractOperationTracer::AbstractOperationTracer(Operation *operation) + : m_operation(nullptr) +{ + // don't create output for that hacky pseudo operation + if (operation->name() != QLatin1String("MinimumProgress")) + m_operation = operation; +} + + +/*! + \inmodule QtInstallerFramework + \class QInstaller::OperationTracer + \brief The OperationTracer prints trace output for starting of operations + and automatically indicates finish on destruction. +*/ + +/*! + Constructs tracer for \a operation. +*/ +OperationTracer::OperationTracer(Operation *operation) + : AbstractOperationTracer(operation) +{ +} + +/*! + Destructs object and prints message indicating finished operation. +*/ +OperationTracer::~OperationTracer() +{ + if (!m_operation) + return; + + qCDebug(QInstaller::lcInstallerInstallLog) << "Done"; +} + +/*! + Prints trace output for starting operation in \a state. +*/ +void OperationTracer::trace(const QString &state) +{ + if (!m_operation) + return; + + qCDebug(lcInstallerInstallLog).noquote() << QString::fromLatin1("%1 %2 operation: %3") + .arg(state, m_operation->value(QLatin1String("component")).toString(), m_operation->name()); + + QStringList args = m_operation->arguments(); + if (m_operation->requiresUnreplacedVariables()) + args = m_operation->packageManager()->replaceVariables(m_operation->arguments()); + + qCDebug(lcInstallerInstallLog).noquote() << QString::fromLatin1("\t- arguments: %1") + .arg(args.join(QLatin1String(", "))); +} + + +/*! + \inmodule QtInstallerFramework + \class QInstaller::ConcurrentOperationTracer + \brief The ConcurrentOperationTracer prints trace output for starting of + asynchronous operations. +*/ + +/*! + Constructs tracer for \a operation. +*/ +ConcurrentOperationTracer::ConcurrentOperationTracer(Operation *operation) + : AbstractOperationTracer(operation) +{ +} + +/*! + Prints trace output for starting operation in \a state. +*/ +void ConcurrentOperationTracer::trace(const QString &state) +{ + if (!m_operation) + return; + + qCDebug(lcInstallerInstallLog).noquote() << QString::fromLatin1("%1 %2 concurrent operation: %3") + .arg(state, m_operation->value(QLatin1String("component")).toString(), m_operation->name()); + + QStringList args = m_operation->arguments(); + if (m_operation->requiresUnreplacedVariables()) + args = m_operation->packageManager()->replaceVariables(m_operation->arguments()); + + qCDebug(lcInstallerInstallLog).noquote() << QString::fromLatin1("\t- arguments: %1") + .arg(args.join(QLatin1String(", "))); + + qCDebug(QInstaller::lcInstallerInstallLog) << "Started"; +} + +} // namespace QInstaller diff --git a/src/libs/installer/operationtracer.h b/src/libs/installer/operationtracer.h new file mode 100644 index 000000000..ce479662c --- /dev/null +++ b/src/libs/installer/operationtracer.h @@ -0,0 +1,68 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#ifndef OPERATIONTRACER_H +#define OPERATIONTRACER_H + +#include "qinstallerglobal.h" +#include "globals.h" + +namespace QInstaller { + +class INSTALLER_EXPORT AbstractOperationTracer +{ +public: + explicit AbstractOperationTracer(Operation *operation); + virtual ~AbstractOperationTracer() = default; + + virtual void trace(const QString &state) = 0; + +protected: + Operation *m_operation; +}; + +class INSTALLER_EXPORT OperationTracer : public AbstractOperationTracer +{ +public: + explicit OperationTracer(Operation *operation); + ~OperationTracer() override; + + void trace(const QString &state) override; +}; + +class INSTALLER_EXPORT ConcurrentOperationTracer : public AbstractOperationTracer +{ +public: + explicit ConcurrentOperationTracer(Operation *operation); + + void trace(const QString &state) override; +}; + +} // namespace QInstaller + +#endif // OPERATIONTRACER_H diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index cfe2cfe09..6764983e4 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -51,6 +51,7 @@ #include "loggingutils.h" #include "concurrentoperationrunner.h" #include "remoteclient.h" +#include "operationtracer.h" #include "selfrestarter.h" #include "filedownloaderfactory.h" @@ -88,41 +89,9 @@ namespace QInstaller { \internal */ -class OperationTracer +static bool runOperation(Operation *operation, Operation::OperationType type) { -public: - OperationTracer(Operation *operation = nullptr) : m_operation(nullptr) - { - if (!operation) - return; - // don't create output for that hacky pseudo operation - if (operation->name() != QLatin1String("MinimumProgress")) - m_operation = operation; - } - void trace(const QString &state) - { - if (!m_operation) - return; - qCDebug(QInstaller::lcInstallerInstallLog).noquote() << QString::fromLatin1("%1 %2 operation: %3") - .arg(state, m_operation->value(QLatin1String("component")).toString(), m_operation->name()); - QStringList args = m_operation->arguments(); - if (m_operation->requiresUnreplacedVariables()) - args = m_operation->packageManager()->replaceVariables(m_operation->arguments()); - qCDebug(QInstaller::lcInstallerInstallLog).noquote() << QString::fromLatin1("\t- arguments: %1") - .arg(args.join(QLatin1String(", "))); - } - ~OperationTracer() { - if (!m_operation) - return; - qCDebug(QInstaller::lcInstallerInstallLog) << "Done"; - } -private: - Operation *m_operation; -}; - -static bool runOperation(Operation *operation, Operation::OperationType type, const bool trace) -{ - OperationTracer tracer = trace ? OperationTracer(operation) : OperationTracer(); + OperationTracer tracer(operation); switch (type) { case Operation::Backup: tracer.trace(QLatin1String("backup")); @@ -370,10 +339,10 @@ bool PackageManagerCorePrivate::isProcessRunning(const QString &name, /* static */ bool PackageManagerCorePrivate::performOperationThreaded(Operation *operation, - Operation::OperationType type, bool trace) + Operation::OperationType type) { QFutureWatcher futureWatcher; - const QFuture future = QtConcurrent::run(runOperation, operation, type, trace); + const QFuture future = QtConcurrent::run(runOperation, operation, type); QEventLoop loop; QObject::connect(&futureWatcher, &decltype(futureWatcher)::finished, &loop, &QEventLoop::quit, diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h index 1a15c6f6c..3a859f63d 100644 --- a/src/libs/installer/packagemanagercore_p.h +++ b/src/libs/installer/packagemanagercore_p.h @@ -75,7 +75,7 @@ public: static bool isProcessRunning(const QString &name, const QList &processes); static bool performOperationThreaded(Operation *op, UpdateOperation::OperationType type - = UpdateOperation::Perform, bool trace = true); + = UpdateOperation::Perform); void initialize(const QHash ¶ms); bool isOfflineOnly() const; diff --git a/src/libs/kdtools/updateoperation.cpp b/src/libs/kdtools/updateoperation.cpp index 8c242e96d..35629809e 100644 --- a/src/libs/kdtools/updateoperation.cpp +++ b/src/libs/kdtools/updateoperation.cpp @@ -120,6 +120,8 @@ UpdateOperation::UpdateOperation(QInstaller::PackageManagerCore *core) , m_core(core) , m_requiresUnreplacedVariables(false) { + qRegisterMetaType(); + // Store the value for compatibility reasons. m_values[QLatin1String("installer")] = QVariant::fromValue(core); } diff --git a/src/libs/kdtools/updateoperation.h b/src/libs/kdtools/updateoperation.h index 0e1c0fbec..a39c25747 100644 --- a/src/libs/kdtools/updateoperation.h +++ b/src/libs/kdtools/updateoperation.h @@ -129,4 +129,6 @@ private: } // namespace KDUpdater +Q_DECLARE_METATYPE(KDUpdater::UpdateOperation *) + #endif // UPDATEOPERATION_H -- cgit v1.2.3