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