File indexing completed on 2024-05-26 05:14:36

0001 /******************************************************************************
0002  *
0003  *  File : preprocessorinstance.h
0004  *  Creation date : Sat 18 Jul 2009 02:50:39
0005  *
0006  *  SPDX-FileCopyrightText: 2009 Szymon Stefanek <s.stefanek at gmail dot com>
0007  *
0008  *  SPDX-License-Identifier: LGPL-2.0-or-later
0009  *
0010  *****************************************************************************/
0011 
0012 #pragma once
0013 
0014 #include <QDateTime>
0015 #include <QObject>
0016 
0017 #include <deque>
0018 
0019 class OrgFreedesktopAkonadiPreprocessorInterface;
0020 
0021 namespace Akonadi
0022 {
0023 namespace Server
0024 {
0025 class PreprocessorManager;
0026 class AgentInstance;
0027 class Tracer;
0028 
0029 /**
0030  * A single preprocessor (agent) instance.
0031  *
0032  * Most of the interface of this class is protected and is exposed only
0033  * to PreprocessorManager (singleton).
0034  *
0035  * This class is NOT thread safe. The caller is responsible of protecting
0036  * against concurrent access.
0037  */
0038 class PreprocessorInstance : public QObject
0039 {
0040     friend class PreprocessorManager;
0041 
0042     Q_OBJECT
0043 
0044 protected:
0045     /**
0046      * Create an instance of a PreprocessorInstance descriptor.
0047      */
0048     PreprocessorInstance(const QString &id, PreprocessorManager &manager, Tracer &tracer);
0049 
0050 public: // This is public only for qDeleteAll() called from PreprocessorManager
0051     // ...for some reason couldn't convince gcc to have it as friend...
0052 
0053     /**
0054      * Destroy this instance of the PreprocessorInstance descriptor.
0055      */
0056     ~PreprocessorInstance() override;
0057 
0058 private:
0059     PreprocessorManager &mManager;
0060     Tracer &mTracer;
0061 
0062     /**
0063      * The internal queue if item identifiers.
0064      * The head item in the queue is the one currently being processed.
0065      * The other ones are waiting.
0066      */
0067     std::deque<qint64> mItemQueue;
0068 
0069     /**
0070      * Is this processor busy ?
0071      * This, in fact, *should* be equivalent to "mItemQueue.count() > 0"
0072      * as the head item in the queue is the one being processed now.
0073      */
0074     bool mBusy = false;
0075 
0076     /**
0077      * The date-time at that we have started processing the current
0078      * item in the queue. This is used to compute the processing time
0079      * and eventually spot a "dead" preprocessor (which takes longer
0080      * than N minutes to process an item).
0081      */
0082     QDateTime mItemProcessingStartDateTime;
0083 
0084     /**
0085      * The id of this preprocessor instance. This is actually
0086      * the AgentInstance identifier.
0087      */
0088     QString mId;
0089 
0090     /**
0091      * The preprocessor D-Bus interface. Owned.
0092      */
0093     OrgFreedesktopAkonadiPreprocessorInterface *mInterface = nullptr;
0094 
0095 protected:
0096     /**
0097      * This is called by PreprocessorManager just after the construction
0098      * in order to connect to the preprocessor instance via D-Bus.
0099      * In case of failure this object should be destroyed as it can't
0100      * operate properly. The error message is printed via Tracer.
0101      */
0102     bool init();
0103 
0104     /**
0105      * Returns true if this preprocessor instance is currently processing an item.
0106      * That is: if we have called "processItem()" on it and it hasn't emitted
0107      * itemProcessed() yet.
0108      */
0109     bool isBusy() const
0110     {
0111         return mBusy;
0112     }
0113 
0114     /**
0115      * Returns the time in seconds elapsed since the current item was submitted
0116      * to the slave preprocessor instance. If no item is currently being
0117      * processed then this function returns -1;
0118      */
0119     qint64 currentProcessingTime();
0120 
0121     /**
0122      * Returns the id of this preprocessor. This is actually
0123      * the AgentInstance identifier but it's not a requirement.
0124      */
0125     const QString &id() const
0126     {
0127         return mId;
0128     }
0129 
0130     /**
0131      * Returns a pointer to the internal preprocessor instance
0132      * item queue. Don't mess with it unless you *really* know
0133      * what you're doing. Use enqueueItem() to add an item
0134      * to the queue. This method is provided to the PreprocessorManager
0135      * to take over the item queue of a dying preprocessor.
0136      *
0137      * The returned pointer is granted to be non null.
0138      */
0139     std::deque<qint64> *itemQueue()
0140     {
0141         return &mItemQueue;
0142     }
0143 
0144     /**
0145      * This is called by PreprocessorManager to enqueue a PimItem
0146      * for processing by this preprocessor instance.
0147      */
0148     void enqueueItem(qint64 itemId);
0149 
0150     /**
0151      * Attempts to abort the processing of the current item.
0152      * May be called only if isBusy() returns true and an assertion
0153      * will remind you of that.
0154      * Returns true if the abort request was successfully sent
0155      * (but not necessarily handled by the slave) and false
0156      * if the request couldn't be sent for some reason.
0157      */
0158     bool abortProcessing();
0159 
0160     /**
0161      * Attempts to invoke the preprocessor slave restart via
0162      * AgentManager. This is the "last resort" action before
0163      * starting to ignore the preprocessor (after it misbehaved).
0164      */
0165     bool invokeRestart();
0166 
0167 private:
0168     /**
0169      * This function starts processing of the first item in mItemQueue.
0170      * It's only used internally.
0171      */
0172     void processHeadItem();
0173 
0174 private Q_SLOTS:
0175 
0176     /**
0177      * This is invoked to signal that the processing of the current (head)
0178      * item has terminated and the next item should be processed.
0179      */
0180     void itemProcessed(qlonglong id);
0181 
0182 }; // class PreprocessorInstance
0183 
0184 } // namespace Server
0185 } // namespace Akonadi