DomT4 / homebrew-autoupdate

:tropical_drink: An easy, convenient way to automatically update Homebrew.
BSD 2-Clause "Simplified" License
987 stars 54 forks source link

Change StartInterval to StartCalendarInterval #59

Closed rechandler12 closed 8 months ago

rechandler12 commented 3 years ago

I suggest changing StartInterval to StartCalendarInterval.

According to documentation StartInterval skips execution if computer is in sleep mode:

StartInterval <integer>
     This optional key causes the job to be started every N seconds. If the system is asleep during the time of the next scheduled interval firing, that interval will be missed due to shortcomings in queue(3).  If
     the job is running during an interval firing, that interval firing will likewise be missed.

StartCalendarInterval will be done right after its awakening and in my opinion this behavior is more desirable.

StartCalendarInterval <dictionary of integers or array of dictionaries of integers>
     This optional key causes the job to be started every calendar interval as specified. Missing arguments are considered to be wildcard. The semantics are similar to crontab(5) in how firing dates are specified.
     Multiple dictionaries may be specified in an array to schedule multiple calendar intervals.

Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up.  If multiple intervals transpire before the computer is woken, those events
     will be coalesced into one event upon wake from sleep.
github-actions[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

swissbuechi commented 9 months ago

I would also suggest to change from StartInterval to StartCalendarInterval. Or at least provide an option to do so. With the current implementation of StartInterval the schedule depends on the time the user boots up his computer, or runs the brew autoupdate start [interval] [options] command (if no reboot occurred since then).

We would need to change the generation of the plist and do some fairly complicated transformations based on the input in seconds. StartCalendarInterval syntax is somehow related to cronjob scheduling.

Example 24h (86400s): brew autoupdate start 86400 [options]

Current:

...
<key>StartInterval</key>
<integer>86400</integer>
...

New: ...

<key>StartCalendarInterval</key>
<dict>
    <key>Minute</key>
    <integer>0</integer>
    <key>Hour</key>
    <integer>12</integer>
</dict>
...

This would run the autoupdate every day at noon. If the computer is sleeping at this time, it would run at the next wake-up.

But how cloud we do this transformation based on the input in seconds? I think this would be way too complicated to implement.

Here are all the possible values:

...
<key>StartCalendarInterval</key>
<dict>
    <key>Minute</key>
    <integer><0-59></integer>
    <key>Hour</key>
    <integer><0-23></integer>
    <key>Day</key>
    <integer><1-31></integer>
    <key>Weekday</key>
    <integer><1-7></integer>
    <key>Month</key>
    <integer><1-12></integer>
</dict>
...

My suggestion would be to let the user type in a schedule instead of an interval: brew autoupdate start [interval or schedule] [options]

We could implement a function which would determine if it is a schedule.

Schedule: Minute-Hour-Day-Weekday-Month

Each input between -< >- would represent an int value based on the available range (for example 0-59 on the first section, which would represent Minute). Writing an * would simulate a wildcard and therefore not even create the field. Leaving a value empty will be interpreted the same as * (0--4-- = 0-*-4-*-*).

Update: Using an * as wildcard is a bad idea, the shell can not parse this as string unless you put it inside quotes like "0-12-*-*-*". I've decided to only support the wildcard defined using an empty value like: 0--4--.

From launchd.plist man page:

Missing arguments are considered to be wildcard

So our "every 24h at noon" example would look the following:

Schedule: 0-12-*-*-* 0-12---

Command: brew autoupdate start 0-12-*-*-* [options] brew autoupdate start 0-12--- [options]


@DomT4 @MikeMcQuaid What do you guys think about my solution approach?

swissbuechi commented 9 months ago

I have now started the implementation of the solution above. https://github.com/swissbuechi/homebrew-autoupdate/tree/add-schedule-configuration

github-actions[bot] commented 8 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.