-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Recover precision when serializing Time
, TimeWithZone
and DateTime
.
#39698
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
Conversation
0af84c2
to
68dc79c
Compare
@pixeltrix I saw that you commented about this in #39648 (comment). Would you mind reviewing this PR? Thank you! |
0 | ||
end | ||
|
||
argument.change(nsec: nsec) |
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.
So this could be replace with the following:
argument.change(nsec: argument.sec_fraction.floor(ActiveJob::Serializers.time_precision) * 1000000000)
Which got me thinking that may be we should add floor
method to Time
🤔
class Time
def floor(precision = 0)
change(nsec: sec_fraction.floor(precision) * 1000000000)
end
end
In which case that code would now be
argument.floor(ActiveJob::Serializers.time_precision)
Another alternative would be to add :sec_fraction
to the list of keys to change
, e.g:
argument.change(sec_fraction: argument.sec_fraction.floor(ActiveJob::Serializers.time_precision))
this would be fairly easy since we calculate the second fraction internal from :nsec
or :usec
. In fact we could make both changes to simplify the floor
method to just this:
class Time
def floor(precision = 0)
change(sec_fraction: sec_fraction.floor(precision))
end
end
Can you do a separate PR to add these and we can have a discussion about them - seems like they'd be useful additions. If they're added then we can update this PR to use them.
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 don't think we should add an option for this. We should just always serialize with the max precision that makes sense.
That would be a breaking change though, wouldn't it? |
@rafaelfranca Dropping the precision seems to be an intentional change from #35713. The concern was specifically around the size of the job payloads.
|
I'm not sure if I consider this a breaking change given we are just adding information, not removing it. Yes, if you were doing something with the time objects and you expected it to have lost precision, that will break you app, but this is the same as any bug fix change we do. If you expect framework to do X, but X is a bug and we fix, your code will break. About the option, do you think any user would chose to lose precision when serializing an object if given them the option? If they wouldn't chose that why are we allowing them the chose? We dropped precision in the assertion, and that is an ok thing to do, if we don't care about the precision in the assertion. But if the lack of precision is changing the behavior in production code, so it is not ok to drop the precision. Adding 10 characters more to in the payload to keep precision seems to be a nice trade-off. |
If we are still concerned about backward compatibility I'm not opposed to add an option like |
What if we forget about the option, store the full precision and just add patches to Active Support to ensure that
As you say it's unlikely that most apps are expecting to be losing precision so won't notice the difference. |
Actually if I think about it more now, I think it shouldn't be a default precision of 10. Instead, we should maintain the precision of the
If we get an object with a precision of 5, we should serialized it with a precision of 5. @pixeltrix I guess we're adding the methods for Ruby versions smaller than 2.7? In Ruby 2.7, |
How would you know an object has a precision of 5? You'd have to do something like this:
Yes, it's something we've done before for other methods. |
We can count the number of decimal places of the float obtained by converting
|
08a34e7
to
adff749
Compare
adff749
to
5f01a3f
Compare
ActiveJob.time_precision
config option for time serializers.Time
, TimeWithZone
and DateTime
.
@pixeltrix @rafaelfranca So I couldn't find a decent way to determine the precision of a
@pixeltrix I'm having trouble with implementing
If our only concern here is for users to be able to lose precision, I guess |
Can you be a bit more specific about the problems you're facing? If you specify the second fraction as a rational and not a float don't the issues with representation go away? |
I'm stuck on figuring a way in replicating the following
Note how the fractional second is different. I think this is due to the behavior described in the Ruby bug report where
We don't have control over what kind of |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
This is still relevant. |
Thank you for reviewing @rafaelfranca @pixeltrix |
* Allows instrumenters to more accurately deduce queue wait time * Retains IS08601 compatibility References #39698
Resolves #39648
Related #35713