Infinite loop when invoking #first
This enters an infinite loop:
schedule = IceCube::Schedule.new(Time.current) do |schedule|
schedule.add_recurrence_rule IceCube::IcalParser.rule_from_ical("FREQ=YEARLY;INTERVAL=1;BYMONTHDAY=31;BYMONTH=2")
end
schedule.first(2) # hangs!
We have patched this internally with:
module ValidatedRuleWithInfiniteRecursionGuard
private
MAX_LOOPS = 10_000
def find_acceptable_time_before(boundary)
count = 0
until finds_acceptable_time? || count > MAX_LOOPS
return false if past_closing_time?(boundary)
count += 1
end
true
end
end
IceCube::ValidatedRule.prepend(ValidatedRuleWithInfiniteRecursionGuard)
I'm happy to submit a fix to the library. It could be the specific patch suggested above, but the several loop and until usages inside the library, combined with the complex logic, looks like a liability. I think a better patch would be to replace the current loop and until usages with safe_ versions that control a max number of iterations to prevent these infinite loops by design. For example:
safe_loop do # m = 10_000 or whatever by default, and can be passed by parameter
end
What do you think?
Similar to https://github.com/ice-cube-ruby/ice_cube/issues/469
I think it's probably better to ensure the rule is valid, rather than break out of an infinite loop. Although, it would obviously be better to gracefully handle an infinite loop than crash.
For example, #554 will fix the issue raised in #469, but does not handle infinite loops.