-
Notifications
You must be signed in to change notification settings - Fork 938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cc/cron: fix blacklist issues #1799
base: dev
Are you sure you want to change the base?
Conversation
Signed-off-by: SoggySaussages <[email protected]>
Currently, cron parse parses a * in hours the same as 0,1,2...,23, and similar for dow. This poses an issue since 0,1,2...,23 != *. Now if all hours/dows are set, the parse will leave the input unchanged rather than forcing "*"s to "0,1,2...23"s. Signed-off-by: SoggySaussages <[email protected]>
if month/dom and dow are both configured, cron will process them using OR. If user didn't want that, they wouldn't set both in the expression. but if using day of week blacklist, in the way we do it currently that would configure it, and then cron would use OR and mess up the user's schedule if they explicitly avoided this behaviour in their expression. For this reason, this commit now only uses the existing method if month/dom aren't configured, or if week is. Otherwise it will loop recalculation of cron schedule until a new time is found which satisfies the dow blacklist. Signed-off-by: SoggySaussages <[email protected]>
Signed-off-by: SoggySaussages <[email protected]>
Signed-off-by: SoggySaussages <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest removing all the tricky bit manipulation here and leave just the loop. (As in your original PR, the number of iterations can be bounded to a reasonable amount, and knowing Next
is fairly efficient such an implementation should be fine.) The code, as is, seems unfortunately rather fragile now and is very tightly coupled to the cron internals--for instance, we need to know about 1<<63
(the special bit that cron uses to represent *
), which is really an implementation detail.
In general, despite the tests, I do not think the correctness of the code is obvious--and even if it is, is it resilient to future changes to cron internals?--and would rather just always use the loop.
By the way, I know that I suggested reading off SpecSchedule
originally in my comments on your original PR, but I intended that comment to apply only to parsing. I would have commented on this part of the implementation dissuading a rewrite, but given you had already written the code I figured just leaving it be would be fine. But now that it is proving much more tricky to get right than expected, I think the right move is to back out and use the simple, obviously correct loop. My sincere apologies for the confusion.
There was no confusion, you taught me a skill and I applied |
Good point. I did not think about the bound on the number of iterations precisely and underestimated the number. I think the only viable options are to go forward with the approach in this PR or to disable the blacklists for crons entirely. I prefer the latter--frankly crons with blacklists feel like significantly more trouble for little benefit--but perhaps the sail has shipped on that design decision. It is just a thought.
I still remain uncomfortable with the approach in this PR. The magic numbers are not so much the problem; I am more concerned that they are needed at all. As I said earlier:
The tight coupling and reliance on implementation detail cannot be avoided by any refactoring. That said, I do agree that if we want to retain support for blacklists, we should do it using the current approach here, not the loop. |
Limit the edge case backup blacklist checker to 200 iterations
cc/interval: use table-driven tests
The hour/day blacklists were causing difficulties, these fixes address those issues and add more thorough tests for
cron.
Currently, cron parse parses a * in hours the same as 0,1,2...,23, and similar for dow. This poses an issue since
0,1,2...,23 != *. Now if all hours/dows are set, the parse will leave the input unchanged rather than forcing "*"s to
"0,1,2...23"s.
If month/dom and dow are both configured, cron will process them using OR. If user didn't want that, they wouldn't set
both in the expression. but if using day of week blacklist, in the way we do it currently that would configure it, and
then cron would use OR and mess up the user's schedule if they explicitly avoided this behaviour in their expression.
For this reason, this commit now only uses the existing method if month/dom aren't configured, or if week is. Otherwise
it will loop recalculation of cron schedule until a new time is found which satisfies the dow blacklist.
Signed-off-by: SoggySaussages [email protected]