File indexing completed on 2024-12-01 04:33:15
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2005 Dario Massarin <nekkar@libero.it> 0004 Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 */ 0011 0012 #ifndef SCHEDULER_H 0013 #define SCHEDULER_H 0014 0015 #include <QMap> 0016 #include <QObject> 0017 #include <QTimerEvent> 0018 0019 #include "core/job.h" 0020 #include "core/jobqueue.h" 0021 #include "kget_export.h" 0022 0023 /** 0024 * @brief Scheduler class: what handle all the jobs in kget. 0025 * 0026 * This class handles all the jobs in kget. See job.h for further details. 0027 * When we want a job to be executed in kget, we have to add the queue 0028 * that owns the job in the scheduler calling the addQueue(JobQueue *) function. 0029 * 0030 */ 0031 0032 class KGET_EXPORT Scheduler : public QObject 0033 { 0034 Q_OBJECT 0035 0036 friend class SchedulerTest; 0037 0038 public: 0039 enum FailureStatus { 0040 None = 0, 0041 AboutToStall = 1, 0042 Stall = 2, 0043 StallTimeout = 3, 0044 Abort = 4, 0045 AbortTimeout = 5, 0046 Error = 6, 0047 }; 0048 0049 class JobFailure 0050 { 0051 public: 0052 JobFailure() 0053 : status(None) 0054 , time(-1) 0055 , count(0) 0056 { 0057 } 0058 0059 bool isValid() 0060 { 0061 return ((status != None) && (time != -1)); 0062 } 0063 0064 FailureStatus status; 0065 int time; 0066 int count; 0067 0068 bool operator==(JobFailure f) const 0069 { 0070 return ((status == f.status) && (time == f.time)); 0071 } 0072 bool operator!=(JobFailure f) const 0073 { 0074 return ((status != f.status) || (time != f.time)); 0075 } 0076 }; 0077 0078 Scheduler(QObject *parent = nullptr); 0079 ~Scheduler() override; 0080 0081 /** 0082 * Starts globally the execution of the jobs 0083 * 0084 * @see stop() 0085 */ 0086 void start(); 0087 0088 /** 0089 * Stops globally the execution of the jobs 0090 * 0091 * @see start() 0092 */ 0093 void stop(); 0094 0095 /** 0096 * Can be used to suspend the scheduler before doing lenghty operations 0097 * and activating it later again 0098 * 0099 * NOTE does not stop running jobs, just prevents changes to jobs 0100 * HACK this is needed since the scheduler would constantly update the queue 0101 * when stopping starting multiple transfers, this slows down that operation a lot 0102 * and could result in transfers finishing before they are stopped etc. 0103 */ 0104 void setIsSuspended(bool isSuspended); 0105 0106 /** 0107 * The JobQueues will be informed of changes in the network connection 0108 * If there is no network connection then the Scheduler won't act on 0109 * the timerEvent or updateQueue 0110 */ 0111 void setHasNetworkConnection(bool hasConnection); 0112 0113 /** 0114 * Adds a queue to the scheduler. 0115 * 0116 * @param queue The queue that should be added 0117 */ 0118 void addQueue(JobQueue *queue); 0119 0120 /** 0121 * Deletes a queue from the scheduler. 0122 * If some jobs in the given queue are being executed, they are 0123 * first stopped, then removed from the scheduler. 0124 * 0125 * @param queue The queue that should be removed 0126 */ 0127 void delQueue(JobQueue *queue); 0128 0129 /** 0130 * @returns true if there is at least one Job in the Running state 0131 */ 0132 bool hasRunningJobs() const; 0133 0134 /** 0135 * @returns the number of jobs that are currently in a Running state 0136 */ 0137 int countRunningJobs() const; 0138 0139 /** 0140 * This function gets called by the KGet class whenever the settings 0141 * have changed. 0142 */ 0143 void settingsChanged(); 0144 0145 // JobQueue notifications 0146 virtual void jobQueueChangedEvent(JobQueue *queue, JobQueue::Status status); 0147 virtual void jobQueueMovedJobEvent(JobQueue *queue, Job *job); 0148 virtual void jobQueueAddedJobEvent(JobQueue *queue, Job *job); 0149 virtual void jobQueueAddedJobsEvent(JobQueue *queue, const QList<Job *> jobs); 0150 virtual void jobQueueRemovedJobEvent(JobQueue *queue, Job *job); 0151 virtual void jobQueueRemovedJobsEvent(JobQueue *queue, const QList<Job *> jobs); 0152 0153 // Job notifications 0154 virtual void jobChangedEvent(Job *job, Job::Status status); 0155 virtual void jobChangedEvent(Job *job, Job::Policy status); 0156 virtual void jobChangedEvent(Job *job, JobFailure failure); 0157 0158 protected: 0159 /** 0160 * Updates the given queue, starting the jobs that come first in the queue 0161 * and stopping all the other 0162 * 0163 * @param queue the queue to update 0164 */ 0165 void updateQueue(JobQueue *queue); 0166 0167 /** 0168 * @return true if the given job should be running (and this depends 0169 * on the job policy and on its jobQueue status) 0170 * 0171 * @param job the job to evaluate 0172 */ 0173 bool shouldBeRunning(Job *job); 0174 0175 private: 0176 // Virtual QObject method 0177 void timerEvent(QTimerEvent *event) override; 0178 0179 /** 0180 * Calls updateQueue for all queues 0181 * @see updateQueue 0182 */ 0183 void updateAllQueues(); 0184 0185 bool shouldUpdate() const; 0186 0187 private: 0188 QList<JobQueue *> m_queues; 0189 QMap<Job *, JobFailure> m_failedJobs; 0190 0191 int m_failureCheckTimer; 0192 0193 const int m_stallTime; 0194 int m_stallTimeout; 0195 int m_abortTimeout; 0196 bool m_isSuspended; 0197 bool m_hasConnection; 0198 }; 0199 0200 inline bool Scheduler::shouldUpdate() const 0201 { 0202 return !m_isSuspended && m_hasConnection; 0203 } 0204 #endif