Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 the m_last* properties and reprogramming itself (using for instant QTimer::singleShot using m_lastExecution + interval. Or maybe reprogrammation could be done by a Scheduler class which would store a list of Task and reprogram when a finished 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?


  • Lifetime Qt Champion

    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 of AppInitialiser). 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 call AppInitialiser::updateEmployees() on an instance of AppInitialiser, or even a lambda method, let's say every 5 minutes.

    What is the scheduler ?

    The Scheduler doesn't exist yet. On their own, a Task will execute exec() which will call the pointer to member function, then if an interval is set, it will call reprogram itself using a QTimer. When I wrote about a Scheduler, I was saying that a Task can work on its own, but it can also be managed by another class storing them (in a QList for instance) and allow me to show which task was executed when, which error, etc...


  • Lifetime Qt Champion

    @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...


  • Lifetime Qt Champion

    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 the Task 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 the m_depends property I can wait for another Task to emit finished to effectively call schedule() (when I call schedule(), if there is a dependency, the task waits for the dependency's finished() to be emitted, then it calls schedule() on itself. When schedule() doesn't have to wait for anything, it calls QTimer::singleShot() with exec() as the slot, which itself calls the internal m_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