File indexing completed on 2024-06-23 05:07:11

0001 /*
0002     SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QMultiMap>
0010 #include <QMutex>
0011 #include <QThread>
0012 
0013 #include "akthread.h"
0014 #include "entities.h"
0015 
0016 namespace Akonadi
0017 {
0018 namespace Server
0019 {
0020 class Collection;
0021 class PauseableTimer;
0022 
0023 class CollectionScheduler : public AkThread
0024 {
0025     Q_OBJECT
0026 
0027 protected:
0028     explicit CollectionScheduler(const QString &threadName, QThread::Priority priority, QObject *parent = nullptr);
0029 
0030 public:
0031     ~CollectionScheduler() override;
0032 
0033     void collectionChanged(qint64 collectionId);
0034     void collectionRemoved(qint64 collectionId);
0035     void collectionAdded(qint64 collectionId);
0036 
0037     /**
0038      * Sets the minimum timeout interval.
0039      *
0040      * Default value is 5.
0041      *
0042      * @p intervalMinutes Minimum timeout interval in minutes.
0043      */
0044     void setMinimumInterval(int intervalMinutes);
0045     [[nodiscard]] int minimumInterval() const;
0046 
0047     using TimePoint = std::chrono::steady_clock::time_point;
0048 
0049     /**
0050      * @return the timestamp (in seconds since epoch) when collectionExpired
0051      * will next be called on the given collection, or 0 if we don't know about the collection.
0052      * Only used by the unittest.
0053      */
0054     TimePoint nextScheduledTime(qint64 collectionId) const;
0055 
0056     /**
0057      * @return the next timeout
0058      */
0059     std::chrono::milliseconds currentTimerInterval() const;
0060 
0061 protected:
0062     void init() override;
0063     void quit() override;
0064 
0065     virtual bool shouldScheduleCollection(const Collection &collection) = 0;
0066     virtual bool hasChanged(const Collection &collection, const Collection &changed) = 0;
0067     /**
0068      * @return Return cache timeout in minutes
0069      */
0070     virtual int collectionScheduleInterval(const Collection &collection) = 0;
0071     /**
0072      * Called when it's time to do something on that collection.
0073      * Notice: this method is called in the secondary thread
0074      */
0075     virtual void collectionExpired(const Collection &collection) = 0;
0076 
0077     void inhibit(bool inhibit = true);
0078 
0079 private Q_SLOTS:
0080     void schedulerTimeout();
0081     void startScheduler();
0082     void scheduleCollection(/*sic!*/ Akonadi::Server::Collection collection, bool shouldStartScheduler = true);
0083 
0084 private:
0085     using ScheduleMap = QMultiMap<TimePoint /*timestamp*/, Collection>;
0086     ScheduleMap::const_iterator constFind(qint64 collectionId) const;
0087     ScheduleMap::iterator find(qint64 collectionId);
0088     ScheduleMap::const_iterator constLowerBound(TimePoint timestamp) const;
0089 
0090     mutable QMutex mScheduleLock;
0091     ScheduleMap mSchedule;
0092     PauseableTimer *mScheduler = nullptr;
0093     int mMinInterval = 5;
0094 };
0095 
0096 } // namespace Server
0097 } // namespace Akonadi