Sonjli 6 Posted January 22, 2020 Hi, I need to schedule some actions when the time arrives. Something like Windows scheduler does. For example at 12.00am of every day I have to post a rest call on a web site, or at 2.00pm another task. I know it is simple to do it with a standard timer or a polling on system time, but is there a smart solution with OTL? Thanks in advance. Share this post Link to post
David Heffernan 2353 Posted January 23, 2020 Why don't you use the system scheduler? Share this post Link to post
Fr0sT.Brutal 900 Posted January 23, 2020 I've no experience with OTL but a primitive solution comes to mind - launch a task with wait ev := CreateEvent(...) if WaitForSingleObject (ev, ScheduledTime-CurrentTime) = WAIT_TIMEOUT then ... do something scheduled to be able to cancel the wait, additional waitable object will be required and WaitForMultipleObjects instead Share this post Link to post
Sonjli 6 Posted January 23, 2020 4 hours ago, David Heffernan said: Why don't you use the system scheduler? Because I need to be in strict control with the scheduling and I am in cross development (Linux and Windows at least). 1 hour ago, Fr0sT.Brutal said: I've no experience with OTL but a primitive solution comes to mind - launch a task with wait ev := CreateEvent(...) if WaitForSingleObject (ev, ScheduledTime-CurrentTime) = WAIT_TIMEOUT then ... do something scheduled to be able to cancel the wait, additional waitable object will be required and WaitForMultipleObjects instead Interesting... any example? I know I can do something like this in OTL, so a "standard" example could help me to figure out. Share this post Link to post
Fr0sT.Brutal 900 Posted January 23, 2020 (edited) 2 hours ago, Sonjli said: Because I need to be in strict control with the scheduling and I am in cross development (Linux and Windows at least). Interesting... any example? I know I can do something like this in OTL, so a "standard" example could help me to figure out. None except that code snippet but it's trivial. For x-platform you can use System.SyncObjs.TEvent.WaitFor. I couldn't find x-platform method to wait for multiple objects so to cancel the wait you'll have to reset each waitable object (so you'll have to keep a list of them... code becomes less and less short & trivial 🙂 ) Edited January 23, 2020 by Fr0sT.Brutal 1 Share this post Link to post
Lars Fosdal 1793 Posted January 23, 2020 Write a simple scheduler - i,e, a collection of tasks and when / how often you want to run them. Oneshot immediately, oneshot at a specific time, repeating by interval, repeating at fixed points in time, etc. Create a task manager thread that checks the scheduler and queues tasks into a task execution queue. You can have a framework of rules such as tasks not being able to run in parallel, or tasks that should not be queued if already in the queue or being executed, etc. The task manager thread also start the tasks from the execution queue and launch them as separate threads at the appropriate time. You decide how many parallel tasks you can run at a time, and you could even have a task worker thread pool. Share this post Link to post
Sherlock 663 Posted January 23, 2020 1 hour ago, Lars Fosdal said: "A whole lot of stuff" Is all that part of the OTL? Then I definitely have to look into that. Share this post Link to post
Lars Fosdal 1793 Posted January 23, 2020 23 minutes ago, Sherlock said: Is all that part of the OTL? Then I definitely have to look into that. Actually, I wasn't thinking of OTL at all - but that would be worth looking into. I attached a generic scheduler though. I had to clean out some proprietary code, but not much. The idea is that the generic type T is an enumerated type like f.x. TJob = (jobUnknown, jobUpdateFiles, jobPublishPage, jobCleanupOldData, jobEtcEtcEtc); The actual task manager is a different story. It would take me quite some time to "unproprietaryize" that one - and that is really where the work is. GenericScheduler.pas 1 Share this post Link to post
Sherlock 663 Posted January 23, 2020 Ohhh, OK. Thanks. I thought I had been sidestepping an extremely powerful library here. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted January 23, 2020 1 hour ago, Lars Fosdal said: The idea is that the generic type T is an enumerated type like f.x. TJob = (jobUnknown, jobUpdateFiles, jobPublishPage, jobCleanupOldData, jobEtcEtcEtc); I did exactly the same for mine xD 1 Share this post Link to post
David Heffernan 2353 Posted January 23, 2020 (edited) Eventually when you discover all the flaws in your solution you'll come back to using the system scheduler. Edited January 23, 2020 by David Heffernan 1 2 Share this post Link to post
Fr0sT.Brutal 900 Posted January 24, 2020 10 hours ago, David Heffernan said: Eventually when you discover all the flaws in your solution you'll come back to using the system scheduler. Do you mean some API functions or taskschd.msc? Share this post Link to post
David Heffernan 2353 Posted January 24, 2020 5 minutes ago, Fr0sT.Brutal said: Do you mean some API functions or taskschd.msc? API Share this post Link to post
Fr0sT.Brutal 900 Posted January 24, 2020 I suspect this is just an interface to scheduler service, so probably not an option for various reasons Share this post Link to post
David Heffernan 2353 Posted January 24, 2020 Of course it is just an interface to the system task scheduler service. Share this post Link to post
Guest Posted January 24, 2020 I have this running in a legacy windows service. Much neater stuff available today but it goes like this: A worker thread is kicked in action at an interval. Say 2 minutes. An array or a couple of boolean flags exists. The parent thread that starts the worker thread is responsible for setting the flags and the worker for clearing them (after successful execution). Key is that the tread is allowed to finish. It may be a job (check something) that should be done at each thread start. If the worker crash it will not clear the flag and the job will be run again next time (of course, you should send some kind of alert in this case). Also if a job is more than 2 minutes (the interval) then if more is required it will be done on the next run. It uses very basic CriticalSection for the flags. Of course, this solution is very simple and depending on the needs it may fall short and get messy but for just a couple of different actions it will suffice. HTH, /D Share this post Link to post