Odd behavior with Schedule - Looking for tweak to fix

Hi all. Not sure why I caught this - it may have been around a while and I didn't notice or it a recent change - makes no never mind either way.
My driver is giving me about 6-8 loops or iterations I can't figure out why. It only happens with the scheduled tasks runs, which is firing a refresh. When I run refresh via the driver button within - I get only 1 iteration.

On my Date/Time parser - when I hit 'refresh', I get a perfect execution and no problems. I get this in the logs:

When I wait for the schedule - I get this:

Here are the 2 routines involved (runCmd() has no involvement in scheduling or refresh and is too long to include here ...)

Does anyone spot an error I'm not seeing why a schedule execution runs 6-8 iterations but a manual iteration runs only once?

Two thoughts without having looked too closely at the code: does putting the callback method name in quotes change anything? It is documented as a string (though unofficially should work either way). Second, do you see multiple jobs under Scheduled Jobs on the device detail page (keeping in mind this section does not dynamically refresh so only is correct at page load)?

1 Like

Assuming this is the only scheduled job in the code, why not simply issue an “unschedule()” each time refresh is called, regardless of whether or not autoupdate is enabled? This might reduce the chance of multiple, duplicate scheduled jobs from being created.

Hi.
Not honestly sure what you're referring to exactly as a callback method - can you whip an example for me to try?
And I never get multiple scheduled tasks - just the one. it all looks normal regardless if I manually run it or wait for it to execute at it's scheduled time. The difference is if I wait for it to execute automatically - on it's schedule I get multiple runs, if I trigger manually using the device 'refresh' button, I just get a single iteration. Here's my schedule:

I can try moving that as suggested - but I don't see a value in it - it autoupdate is disabled, it's not needed - but I can't see any reason not to give it a try.
I'll run your suggesting through a test set tomorrow.
thx

If you’re not seeing multiple scheduled jobs, then no need to try my suggestion. :thinking: I wonder if the issue has something to do with how the cron scheduler is working? In general, I would not create the scheduled job within the refresh() routine. Instead, schedule() (or unschedule()) a recurring scheduled job in the driver’s updated() routine.

Something like:

def updated () {

unschedule()

if (autoUpdate) schedule(*proper recurring cron expression*, refresh)

}

This is how most drivers handle a recurring scheduled job.

Sorry, I meant the "handler method" and not the "callback method" (I was thinking of other cases where something similar is used), but in your case that would be the refresh() method, the method name you pass to schedule(). You can see that it is documented as a String here: https://docs.hubitat.com/index.php?title=Common_Methods_Object#schedule

So, on line 153 in your code, what I meant was to try "refresh" instead of refresh.

But again, I'm not sure that's really the problem -- just something I like to do since you know it's a String. :smiley:

I second @ogiewon's suggestion. Looks like you're scheduling things to happen at second 0, every AutoUpdateInterval minutes, starting at minute 0, and then your scheduled method itself is also un-doing and re-doing this schedule, so it will likely still be second 0 of that minute for several more executions. I'm also not sure exactly how the scheduler works, but it's possible it will fire if scheduled while that second is still the correct second (not necessarily only right at millisecond 0) -- meaning you'll get stuck in somewhat of a loop for a few executions (if this is correct; again, I'm not sure exactly how the scheduler handles this) when run as part of the schedule, but not when run manually since it (probably) wouldn't be at that exact time.

His idea to move your scheduling to updated() would both (IMHO) make this a bit cleaner and also resolve this issue, if this is indeed it. If this is a driver, your "auto update" setting can't be changed without hitting "Save Preferences," which calls updated() in your driver code, so there's no reason to check the value each time that code gets run--so it shouldn't matter either way.

PS - Conventionally, Groovy variables are camel cased, starting with a lower case letter, so autoUpdateInterval would be a more conventional name. Also not the problem, but can't hurt. :smiley:

1 Like

Only other thought is multiple threads could be running this simultaneously. You can make it single threaded using this setting:

I may always wonder if your thoughts could have solved my problem - I will probably never know! I 'solved' it prior to looking at your solution... but am still grateful for the brain cells burned!

1 Like

Problem resolved - in a roundabout way.
First, thanks for the catch on the Camel... I don't deviate from it, but I think it was something that snaked past me from my editor (I like to use IntelliJ IDEA 2021.2.2).
regarding the double quotes, No impact in either form, however I did wrap the word refresh JIC.

I moved unschedule() to run regardless if a schedule exists or not so it was out of the autoUpdate routine as was recommended. This had no impact on the problem of course, and I suspect it may add a few cycles in some cases, but I didn't really care.

The trigger was the eyeballs that caught the 'always in the same second'... I remembered a year ago a timing issue I had with a driver I'd written and it queued me to stuff a delay. Using runIn(x,x) I was able to wrap my schedule command inside its own routine then call it via runIn with a 1 second delay. Problem solved.

(logs with 2 minutes as autoUpdate value:

Many thanks to each of you for your inputs and knowledge.