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

feat(firestore): Added support for read time #19851

Merged
merged 9 commits into from Jan 24, 2023

Conversation

diptanshumittal
Copy link
Contributor

No description provided.

@diptanshumittal diptanshumittal requested a review from a team as a code owner December 12, 2022 09:22
@product-auto-label product-auto-label bot added the api: firestore Issues related to the Firestore API. label Dec 12, 2022
@diptanshumittal diptanshumittal added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Dec 12, 2022
@diptanshumittal diptanshumittal removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jan 10, 2023

collection_group = firestore.collection_group(rand_col.collection_id)

partitions = collection_group.partitions 6, read_time: read_time
Copy link
Member

Choose a reason for hiding this comment

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

What if there's some time skew between the client and server? Will this test work or will it flake?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To accomodate that we are pausing 1 sec after a DML operation or after setting the read_time. But if skew becomes larger than that, tests will start failing.

Copy link
Member

Choose a reason for hiding this comment

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

Okay, we'll keep an eye on it. I'm just not sure I trust the clock on the Kokoro instances.

return nil if time.nil?

# Force the object to be a Time object.
time = time.to_time.utc
Copy link
Member

Choose a reason for hiding this comment

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

What is this doing? What type could time be, where this kind of conversion would be needed?

I'm asking because all the read_time parameters above are documented to require type Time. This could be problematic by itself because users might want to pass a DateTime, or maybe even a Numeric (representing seconds since the posix Epoch). However, if you require Time, then it seems like this line wouldn't be needed. If this line (or something like it) is needed, and you're supporting some other classes, then those should be called out in the @param documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was done keeping the user perspective in mind. If by mistake wrong data type is given as input, user gets a error like - undefined method 'usec' for String without the above conversion. But with above check , user gets - undefined method 'to_time' for String, which is easy to debug.

Copy link
Member

Choose a reason for hiding this comment

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

If you want to enforce a type, just check the type using is_a? or respond_to? and raise TypeError. That would be more clear.

In this case, I don't think it would work at all, and in fact I'm a bit puzzled why the tests are passing. Because to_time isn't a method of Time, so if you pass Time.now as the read time, I think you'll get a NoMethodError.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then i will update the type check and use is_a? to raise the error.
Checked the ruby docs, they haven't mentioned about to_time method but it is there in the Time class and returns self.

Copy link
Member

Choose a reason for hiding this comment

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

Then i will update the type check and use is_a? to raise the error. Checked the ruby docs, they haven't mentioned about to_time method but it is there in the Time class and returns self.

Really?

▶ irb
irb(main):001:0> RUBY_VERSION
=> "3.1.3"
irb(main):002:0> Time.now.to_time
(irb):2:in `<main>': undefined method `to_time' for 2023-01-13 12:37:57.34993 -0800:Time (NoMethodError)
Did you mean?  to_i
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/bin/irb:25:in `load'
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/bin/irb:25:in `<main>'
irb(main):003:0>

Copy link
Member

Choose a reason for hiding this comment

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

Oh, it looks like it's present if the date library has been loaded.

▶ irb
irb(main):001:0> RUBY_VERSION
=> "3.1.3"
irb(main):002:0> Time.now.to_time
(irb):2:in `<main>': undefined method `to_time' for 2023-01-13 12:37:57.34993 -0800:Time (NoMethodError)
Did you mean?  to_i
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/bin/irb:25:in `load'
	from /Users/dazuma/.asdf/installs/ruby/3.1.3/bin/irb:25:in `<main>'
irb(main):003:0> require "date"
=> true
irb(main):004:0> Time.now.to_time
=> 2023-01-13 12:39:20.768914 -0800
irb(main):005:0>

which is an annoying quirk in Ruby's standard library. I don't think we should be depending on it.


collection_group = firestore.collection_group(rand_col.collection_id)

partitions = collection_group.partitions 6, read_time: read_time
Copy link
Member

Choose a reason for hiding this comment

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

Okay, we'll keep an eye on it. I'm just not sure I trust the clock on the Kokoro instances.

return nil if time.nil?

# Force the object to be a Time object.
time = time.to_time.utc
Copy link
Member

Choose a reason for hiding this comment

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

If you want to enforce a type, just check the type using is_a? or respond_to? and raise TypeError. That would be more clear.

In this case, I don't think it would work at all, and in fact I'm a bit puzzled why the tests are passing. Because to_time isn't a method of Time, so if you pass Time.now as the read time, I think you'll get a NoMethodError.

from: [Google::Cloud::Firestore::V1::StructuredQuery::CollectionSelector.new(collection_id: "users", all_descendants: false)]
)
firestore_mock.expect :run_query, query_results_enum, run_query_args(expected_query, new_transaction: read_only_transaction_opt)
# firestore_mock.expect :commit, empty_commit_resp, commit_args(transaction: transaction_id)
Copy link
Member

Choose a reason for hiding this comment

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

Please don't leave commented out code. Either uncomment or delete the line. If the line is meant to be disabled temporarily, include a clear comment detailing why it's disabled and when it should be re-enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad.. Forgot to remove the line. Will fix this.

def read_time_to_timestamp read_time
return nil if read_time.nil?

raise TypeError, "read_time is expected to be a Time object" unless read_time.is_a? Time
Copy link
Member

Choose a reason for hiding this comment

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

Thinking about this some more, I'm now actually inclined not even to have this current check here, but just let it say NoMethodError: usec if users pass a non-Time-compatible object. Ruby types are duck-types, and it's not common to check for specific classes. But we can just leave it in for now; removing it later is not a breaking change.

@diptanshumittal diptanshumittal merged commit 0c90e74 into main Jan 24, 2023
@diptanshumittal diptanshumittal deleted the feat_firestore_read_time branch January 24, 2023 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: firestore Issues related to the Firestore API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants