Skip to content
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

Prevent server blow up when iterating over TimeWithZone Range #11474

Merged
merged 1 commit into from
Sep 22, 2013

Conversation

bogdan
Copy link
Contributor

@bogdan bogdan commented Jul 17, 2013

Iterating over a Range of Time is impossible in ruby:

((Time.now - 1.month)..Time.now).to_a # raises TypeError: can't iterate from Time

But it is still possible with ActiveSupport::TimeWithZone

((Time.now.in_time_zone - 1.month)..Time.now.in_time_zone).to_a
    # => Tons of deprecations blow up your console

In good case current process is stuck with IO.
In worth case server disk space blow up with production.log file.

This was a huge problem for us and caused a down time on our production app.

In order to prevent that we can generate #succ deprecation warning only once.
And remove TimeWithZone#succ as soon as Time#succ will be removed.

@senny
Copy link
Member

senny commented Jul 17, 2013

@pixeltrix can you take a look?

@pixeltrix
Copy link
Contributor

I think I'd rather override Range to check if it acts_like?(:time) and raise TypeError: can't iterate from Time - it's what they do internally in Ruby.

@bogdan
Copy link
Contributor Author

bogdan commented Jul 18, 2013

Reworked as @pixeltrix suggested.

@pixeltrix
Copy link
Contributor

@bogdan you might need to do Range#step as well - also test that Range#include? raises the error.

Also you probably need to require 'active_support/core_ext/object/acts_like' as one of the Active Model tests is failing with a NoMethodError.

@bogdan
Copy link
Contributor Author

bogdan commented Jul 18, 2013

@pixeltrix made all changes you've suggested.


def step_with_time_with_zone(n = 1, &block)
ensure_iteration_allowed
step_withot_time_with_zone(n, &block)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be step_without_time_with_zone 😉

@ghost ghost assigned pixeltrix Sep 22, 2013
pixeltrix added a commit that referenced this pull request Sep 22, 2013
Prevent server blow up when iterating over TimeWithZone Range
@pixeltrix pixeltrix merged commit ffc8abd into rails:master Sep 22, 2013
pixeltrix added a commit that referenced this pull request Sep 22, 2013
Prevent server blow up when iterating over TimeWithZone Range
@pixeltrix
Copy link
Contributor

@bogdan thanks - sorry for the delay

@bogdan
Copy link
Contributor Author

bogdan commented Sep 23, 2013

I would backport it to 3.2 as it is critical issue when people migrate from 1.8 to 1.9.

But it is for you to decide.

bogdan added a commit to bogdan/rails that referenced this pull request Sep 23, 2013
rafaelfranca added a commit that referenced this pull request Sep 23, 2013
rafaelfranca added a commit that referenced this pull request Sep 23, 2013
Changelog entry for pr #11474
Conflicts:
	activesupport/CHANGELOG.md
@mjtko
Copy link
Contributor

mjtko commented Dec 4, 2013

@pixeltrix @bogdan The merge of this has broken iteration over DateTime objects as, with the core extensions, they rightly indicate that they act like a time object. However, this is a change from standard Ruby behaviour, so I believe this to be a bug.

I can monkey patch for now - my solution is to raise only if it acts_like_time? but doesn't acts_like_date?. How does that sound? I can throw together a PR if that seems like a sensible solution to you.

@bogdan
Copy link
Contributor Author

bogdan commented Dec 4, 2013

@mjtko I personally was against those acts_like magic.
If this patch disallows iteration over DateTime than we should fix it as ruby itself allows it.

So, I agree.

@mjtko
Copy link
Contributor

mjtko commented Dec 4, 2013

@bogdan Yeah, I was looking for your original patch pre-acts_like, but Github doesn't want me to find it easily, so I gave up. :) Do you still have it somewhere?

@bogdan
Copy link
Contributor Author

bogdan commented Dec 4, 2013

@mjtko didn't find it with git fsck. Maybe push --force make it lost forever.

@pixeltrix
Copy link
Contributor

😧 I didn't realise that you can't iterate over Time but you can over DateTime. I suspect this maybe an unintentional side effect of DateTime < Date - I guess changing the check to is_a?(Time) will work, okay with you @bogdan ?

@bogdan
Copy link
Contributor Author

bogdan commented Dec 4, 2013

@pixeltrix sure.

Its quite strange that ruby iterates over DateTime in the same way as over Date but not as Time. We didn't take that into count in this patch.

@madwire
Copy link

madwire commented Jan 10, 2014

Any news on this problem? Just had to monkey patch the Range Class 😟

@pixeltrix
Copy link
Contributor

@madwire do you mean the original issue or that DateTime ranges can't be iterated?

@madwire
Copy link

madwire commented Jan 10, 2014

@pixeltrix sorry I mean the DateTime issue

pixeltrix added a commit that referenced this pull request Nov 7, 2017
In #11474 we prevented TWZ ranges being iterated over which matched
Ruby's handling of Time ranges and as a consequence `include?` stopped
working with both Time ranges and TWZ ranges. However in
ruby/ruby@b061634 support was added for `include?` to use `cover?` for
'linear' objects. Since we have no way of making Ruby consider TWZ
instances as 'linear' we have to override `Range#include?`.

Fixes #30799.
pixeltrix added a commit that referenced this pull request Nov 8, 2017
In #11474 we prevented TWZ ranges being iterated over which matched
Ruby's handling of Time ranges and as a consequence `include?` stopped
working with both Time ranges and TWZ ranges. However in
ruby/ruby@b061634 support was added for `include?` to use `cover?` for
'linear' objects. Since we have no way of making Ruby consider TWZ
instances as 'linear' we have to override `Range#include?`.

Fixes #30799.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants