Write Scheduler to run different pointer to member
-
I'm writing an app for an unreliable environment (power side and internet connection). So, on startup, I update local data from an API and save them to a local
SQlite
database, all tables but 2 are read-only.My idea was to write a
Task
class like so:class Task : public QObject { Q_OBJECT private: QString m_name; const QObject *m_receiver; const char *m_method; QDateTime m_firstExecution; int frequency; QDateTime m_lastExecution; bool m_lastStatus; QString m_failedReason; public: // Getters/Setters void exec(); // Signals and slots };
The way I see it: A task stores a receiver object and a method/slot name, like when using
SLOT()
keyword, just because I don't have any idea how to be more generic.Task::exec()
would be in charge of starting the method, settings them_last*
properties and reprogramming itself (using for instantQTimer::singleShot
usingm_lastExecution
+interval
. Or maybe reprogrammation could be done by aScheduler
class which would store a list ofTask
and reprogram when afinished
signal is emitted...What do you guys think of this? Is it a good way to do it? Is there a way to be more by accepting any kind of receiver and a pointer to a member function? Any idea of improvements?
-
Hi,
There are some pieces missing.
What should these tasks be ?
What is the scheduler ? -
@SGaist said in Write Scheduler to run different pointer to member:
What should these tasks be ?
Currently I have an
AppInitialiser
class which updates all the tables from a web API. So for now, I just need to call some of its methods (Pointers to members ofAppInitialiser
). But I would like the tasks to be generic, and maybe call other object's methods.A
Task
is simply a wrapper around a pointer to method and an interval. For instance, I can use it to callAppInitialiser::updateEmployees()
on an instance ofAppInitialiser
, or even a lambda method, let's say every 5 minutes.What is the scheduler ?
The
Scheduler
doesn't exist yet. On their own, aTask
will executeexec()
which will call the pointer to member function, then if an interval is set, it will call reprogram itself using aQTimer
. When I wrote about aScheduler
, I was saying that aTask
can work on its own, but it can also be managed by another class storing them (in aQList
for instance) and allow me to show which task was executed when, which error, etc... -
@Max13 said in Write Scheduler to run different pointer to member:
let's say every 5 minutes.
See QTimer
-
@Christian-Ehrlicher said in Write Scheduler to run different pointer to member:
See QTimer
Thanks for your answer, but while
QTimer
is definitely an essential class I plan on using (I also referred to it in my previous post), my concerns are more about how I can make a generic task manager.Today, for my current project, I just need to call some members on a single object, but if I think big, I wonder how I can store them, handle them, get feedback, make them execute any kind of job (from any types of object, not from the same type/instance), a table widget showing their statuses, etc...
-
I still don't see why a QTimer isn't enough - it can be started, stopped, can be run once or more, can execute any function given with any kind of parameters, even a lambda, ... there is nothing your description requires you to store the PMF by your own. But maybe QMetaMethod is something you can take a look on
-
@chehrlic said in Write Scheduler to run different pointer to member:
I still don't see why a QTimer isn't enough - it can be started, stopped, can be run once or more, can execute any function given with any kind of parameters, even a lambda, ... there is nothing your description requires you to store the PMF by your own. But maybe QMetaMethod is something you can take a look on
Well, like you said,
QTimer
alone could be enough at first sight, but if I want to "manage" them, or even organize them, I need a wrapper with some human-readable data. That's when theTask
class comes handy.This is my current
Task
class, as of today:class Task : public QObject { Q_OBJECT public: typedef std::function<bool(QString&)> Function; private: QString m_name; Function m_function; QDateTime m_firstExec; int m_frequency; const Task *m_depends; QDateTime m_lastExec; bool m_lastStatus; QString m_failedReason; QMetaObject::Connection m_dependCnt; public: // Constructors/Getters/Setters signals: void starting(); void finished(bool status); public slots: void schedule(); void exec(); };
I'm stuck with a single type of
Function
stored (bool (QString&)
), with them_depends
property I can wait for anotherTask
to emit finished to effectively callschedule()
(when I callschedule()
, if there is a dependency, the task waits for the dependency'sfinished()
to be emitted, then it callsschedule()
on itself. Whenschedule()
doesn't have to wait for anything, it callsQTimer::singleShot()
withexec()
as the slot, which itself calls the internalm_function
stored.So I'm using a
QTimer
in the end, but with some extra properties. Except being stuck with a single type of function (I'm storing lambdas for now), I'm pretty happy with that, moreover if I need to build a widget showing the status of each of them.I will look at
QMetaMethod
also, thanks for your suggestions