TimerPeriod Question

Hey all,

I’m working on giving users the ability to schedule tasks and events in one of my apps. Right now, after an event is scheduled, I set up a timer and calculate the period of that timer to be between now and the selected time/date the user selected. This works well, except that I’ve just discovered that it’s possible to get a period larger than the range of the integer data type. Both the legacy framework timer and the Xojo framework timer have their period datatype set to Integer. Therefore, you can’t set a period longer than 2,147,483,647 milliseconds in 32 bit mode which is about 24.85 days. 64 bit shouldn’t be a problem, but not everyone is using 64 bit yet and I can’t debug in 64 bit.

Anyone have any suggestions? I hold all of these “event” timers in a dictionary. I’m thinking of having a master timer cycle through this dictionary every 24 hours and start those timers which are due to fire in 24 hours or less. That way, my period is always reasonable. I wanted to see if anyone had any other ideas.

Thanks,

Jon

Instead of using the timer itself to schedule the task, how about storing the time and date of the event and the details of the event and task somewhere (SQLite DB? - or elsewhere), and use the timer to periodically check if the time and date of an event occurs. When the time and date for an event occurs, then launch the appropriate task.

I see one possibility : when the timer fires, look if the required period is longer than the maximum, and instead of doing what you are supposed to do, reset the timer to the remainder, or the maximum if it is even longer than that, for another interim period.

Of course if the timer has reached a time within boundaries, you do whatever is supposed to happen.

That means having a variable stocking the actual period you wish.

I believe this can be made into a convenient subclass that will not have the period limitation.

Louis’ idea seems easier to implement as a subclass. On long periods, no need to have a millisecond resolution. A multiple timer with period 1000 checking TotalSeconds could very well manage long periods.

similar to Louis’s idea, you can store the longer time task schedule into a local file, like xml file (you have root node of each specific user, then set different tag for year, month, date, time, etc.) or similar. Then set up a mechanism to periodically check the year/month/date with current time/date data. For example, you can set this check in the open event of your app. And moreover, you can store this file under each user’s name directory, thus, you don’t need to connect to a database. The drawback of this method I can think about is without database, you could not handle large amount of data.

It is probably easier to have an instance per user.

Or, maybe use the builtin cron to execute the scheduled tasks?

man crontab

That would handle everything on OS X and Linux, at least. For Windows, you could install schtasks:
https://technet.microsoft.com/en-us/library/cc725744.aspx

Simple, here is a timer with a resolution of one second, with period in Uint64.

longtimer.xojo_binary_project

I used classic framework so all users including late RS versions can use that class.

Enjoy !

Yes. That can be done. However, not everything is a stored actual date. Setting something to execute every other Friday or the 2nd Tuesday of each month isn’t a specific date. So I have to actually calculate when the next date will be. Sure, I could store that next date in my database but why not just keep it in memory. The next time I restart the program, I’ll have to calculate it again anyhow. The point is, you still need a timer to execute the event.

So your statement, “periodically check if the time and date of an event occurs.” Well, how often is periodically? If it’s hourly, then what if I have an event set to start at 9:30? I can’t fire the event early nor late, but my “periodic” checking is going to miss the event. OK, so I check it every minute. Really? Why do that. That’s why I create a timer to execute the event the period of which is from “now” until the time of the event. So one needs to create a timer to do the event.

[quote=291718:@Michel Bujardet]I see one possibility : when the timer fires, look if the required period is longer than the maximum, and instead of doing what you are supposed to do, reset the timer to the remainder, or the maximum if it is even longer than that, for another interim period.

Of course if the timer has reached a time within boundaries, you do whatever is supposed to happen.

That means having a variable stocking the actual period you wish.

I believe this can be made into a convenient subclass that will not have the period limitation.[/quote]

Yeah, that’s a good idea. I like your thinking there.

Seems like a waste to have something firing that often checking a date, then you can set a timer for a specific event that will occur when you want. And with multiple events scheduled, it seems like a lot for one timer to manage…

[quote=291803:@Tim Jones]Or, maybe use the builtin cron to execute the scheduled tasks?

man crontab

That would handle everything on OS X and Linux, at least. For Windows, you could install schtasks:
https://technet.microsoft.com/en-us/library/cc725744.aspx[/quote]

Yeah, but that’s more for system or OS level tasks than doing something inside my app. Yes, I have an API that a shell could communicate with but that gets quite messy.

Is your app daemonized, or is it just running all the time? It just feels very odd to run an app live just to manage scheduled tasks that could be weeks away. What happens if the system is rebooted? Or the user logs out?

Eventually I plan to daemonize it. Right now that’s not the case. Yes, tasks could be weeks away. I store all of the tasks in a database. When the app starts up it loads its settings from the database including the saved tasks. It then calculates the time until each task and creates a dictionary of timers accordingly. And yes, I get it if the program is not running when a specific task is supposed to happen, it gets missed. Yep. But this app is a control system and most customers leave it running all the time as it is.

But yes, creating a background daemonized “engine” and then using the desktop app as basically the UI for it is in my long term plans.

[quote=291808:@Michel Bujardet]Simple, here is a timer with a resolution of one second, with period in Uint64.

longtimer.xojo_binary_project

I used classic framework so all users including late RS versions can use that class.

Enjoy ![/quote]

Very clever idea!

I have a helper app that checks every minute if the time to do something has come. There have been headaches with this approach. Mainly, the need for an installer has come with the helper app because with a new version the helper app needs to be running, too. And making sure that the helper app starts when the computer restarts is also fun.

Thanks all for the help. I decided to use my original approach and have a master timer that runs on a 24 hour period that checks all the queued events to see if they are due to execute within 24 hours. If so, then I calculate that time period and start those timers. I have this master timer set up as a singleton with a shared method that I call when I want it to do its thing. So when the program starts, it runs this method which checks the dates of all the events and starts those that needed it. It then resets itself and starts its 24 hour period. The action event of the timer calls this same shared method.

I thought long and hard about Michel’s clever timer. I like it a lot but I was just concerned about having a bunch of those firing code every second for who knows how long. Seems like a potential waste. Also seems better not to have timers hanging out with long periods in the first place with this new 24 hour check.

All I can say is this whole ability to schedule actions and events inside an application is not a trivial thing at all! :slight_smile:

I picked one second because I had no idea of the final resolution you needed. It could just as well be one or dozen minutes.