google-cloud-firestore 2.0.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,17 +41,21 @@ module Google
41
41
  # listener.stop
42
42
  #
43
43
  class QueryListener
44
+ include MonitorMixin
44
45
  ##
45
46
  # @private
46
47
  # Creates the watch stream and listener object.
47
48
  def initialize query, &callback
49
+ super() # to init MonitorMixin
50
+
48
51
  @query = query
49
52
  raise ArgumentError if @query.nil?
50
53
 
51
54
  @callback = callback
52
55
  raise ArgumentError if @callback.nil?
56
+ @error_callbacks = []
53
57
 
54
- @listener = Watch::Listener.for_query query, &callback
58
+ @listener = Watch::Listener.for_query self, query, &callback
55
59
  end
56
60
 
57
61
  ##
@@ -112,6 +116,83 @@ module Google
112
116
  def stopped?
113
117
  @listener.stopped?
114
118
  end
119
+
120
+ ##
121
+ # Register to be notified of errors when raised.
122
+ #
123
+ # If an unhandled error has occurred the listener will attempt to
124
+ # recover from the error and resume listening.
125
+ #
126
+ # Multiple error handlers can be added.
127
+ #
128
+ # @yield [callback] The block to be called when an error is raised.
129
+ # @yieldparam [Exception] error The error raised.
130
+ #
131
+ # @example
132
+ # require "google/cloud/firestore"
133
+ #
134
+ # firestore = Google::Cloud::Firestore.new
135
+ #
136
+ # # Create a query
137
+ # query = firestore.col(:cities).order(:population, :desc)
138
+ #
139
+ # listener = query.listen do |snapshot|
140
+ # puts "The query snapshot has #{snapshot.docs.count} documents "
141
+ # puts "and has #{snapshot.changes.count} changes."
142
+ # end
143
+ #
144
+ # # Register to be notified when unhandled errors occur.
145
+ # listener.on_error do |error|
146
+ # puts error
147
+ # end
148
+ #
149
+ # # When ready, stop the listen operation and close the stream.
150
+ # listener.stop
151
+ #
152
+ def on_error &block
153
+ raise ArgumentError, "on_error must be called with a block" unless block_given?
154
+ synchronize { @error_callbacks << block }
155
+ end
156
+
157
+ ##
158
+ # The most recent unhandled error to occur while listening for changes.
159
+ #
160
+ # If an unhandled error has occurred the listener will attempt to
161
+ # recover from the error and resume listening.
162
+ #
163
+ # @return [Exception, nil] error The most recent error raised.
164
+ #
165
+ # @example
166
+ # require "google/cloud/firestore"
167
+ #
168
+ # firestore = Google::Cloud::Firestore.new
169
+ #
170
+ # # Create a query
171
+ # query = firestore.col(:cities).order(:population, :desc)
172
+ #
173
+ # listener = query.listen do |snapshot|
174
+ # puts "The query snapshot has #{snapshot.docs.count} documents "
175
+ # puts "and has #{snapshot.changes.count} changes."
176
+ # end
177
+ #
178
+ # # If an error was raised, it can be retrieved here:
179
+ # listener.last_error #=> nil
180
+ #
181
+ # # When ready, stop the listen operation and close the stream.
182
+ # listener.stop
183
+ #
184
+ def last_error
185
+ synchronize { @last_error }
186
+ end
187
+
188
+ # @private Pass the error to user-provided error callbacks.
189
+ def error! error
190
+ error_callbacks = synchronize do
191
+ @last_error = error
192
+ @error_callbacks.dup
193
+ end
194
+ error_callbacks.each { |error_callback| error_callback.call error }
195
+ end
115
196
  end
116
197
  end
117
198
  end
@@ -321,7 +321,7 @@ module Google
321
321
 
322
322
  doc_path = coalesce_doc_path_argument doc
323
323
 
324
- @writes << Convert.writes_for_create(doc_path, data)
324
+ @writes << Convert.write_for_create(doc_path, data)
325
325
 
326
326
  nil
327
327
  end
@@ -422,7 +422,7 @@ module Google
422
422
 
423
423
  doc_path = coalesce_doc_path_argument doc
424
424
 
425
- @writes << Convert.writes_for_set(doc_path, data, merge: merge)
425
+ @writes << Convert.write_for_set(doc_path, data, merge: merge)
426
426
 
427
427
  nil
428
428
  end
@@ -526,8 +526,8 @@ module Google
526
526
 
527
527
  doc_path = coalesce_doc_path_argument doc
528
528
 
529
- @writes << Convert.writes_for_update(doc_path, data,
530
- update_time: update_time)
529
+ @writes << Convert.write_for_update(doc_path, data,
530
+ update_time: update_time)
531
531
 
532
532
  nil
533
533
  end
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Firestore
19
- VERSION = "2.0.0".freeze
19
+ VERSION = "2.4.1".freeze
20
20
  end
21
21
  end
22
22
  end
@@ -127,6 +127,8 @@ module Google
127
127
  end
128
128
 
129
129
  def current_docs
130
+ # Reverse the results for Query#limit_to_last queries since that method reversed the order_by directions.
131
+ return @tree.keys.reverse if @query&.limit_type == :last
130
132
  @tree.keys
131
133
  end
132
134
 
@@ -30,7 +30,7 @@ module Google
30
30
  class Listener
31
31
  include MonitorMixin
32
32
 
33
- def self.for_doc_ref doc_ref, &callback
33
+ def self.for_doc_ref parent, doc_ref, &callback
34
34
  raise ArgumentError if doc_ref.nil?
35
35
  raise ArgumentError if callback.nil?
36
36
 
@@ -44,10 +44,10 @@ module Google
44
44
  )
45
45
  )
46
46
 
47
- new nil, doc_ref, doc_ref.client, init_listen_req, &callback
47
+ new parent, nil, doc_ref, doc_ref.client, init_listen_req, &callback
48
48
  end
49
49
 
50
- def self.for_query query, &callback
50
+ def self.for_query parent, query, &callback
51
51
  raise ArgumentError if query.nil?
52
52
  raise ArgumentError if callback.nil?
53
53
 
@@ -61,12 +61,13 @@ module Google
61
61
  )
62
62
  )
63
63
 
64
- new query, nil, query.client, init_listen_req, &callback
64
+ new parent, query, nil, query.client, init_listen_req, &callback
65
65
  end
66
66
 
67
- def initialize query, doc_ref, client, init_listen_req, &callback
67
+ def initialize parent, query, doc_ref, client, init_listen_req, &callback
68
68
  super() # to init MonitorMixin
69
69
 
70
+ @parent = parent
70
71
  @query = query
71
72
  @doc_ref = doc_ref
72
73
  @client = client
@@ -119,6 +120,8 @@ module Google
119
120
 
120
121
  def send_callback query_snp
121
122
  @callback.call query_snp
123
+ rescue StandardError => e
124
+ @parent.error! e
122
125
  end
123
126
 
124
127
  def start_listening!
@@ -270,25 +273,29 @@ module Google
270
273
  @request_queue.push self
271
274
  rescue GRPC::Cancelled, GRPC::DeadlineExceeded, GRPC::Internal,
272
275
  GRPC::ResourceExhausted, GRPC::Unauthenticated,
273
- GRPC::Unavailable, GRPC::Core::CallError
276
+ GRPC::Unavailable, GRPC::Core::CallError => e
274
277
  # Restart the stream with an incremental back for a retriable error.
275
278
  # Also when GRPC raises the internal CallError.
276
279
 
277
- # Re-raise if retried more than the max
278
- raise err if @backoff[:current] > @backoff[:max]
279
-
280
- # Sleep with incremental backoff before restarting
281
- sleep @backoff[:delay]
280
+ # Raise if retried more than the max
281
+ if @backoff[:current] > @backoff[:max]
282
+ @parent.error! e
283
+ raise e
284
+ else
285
+ # Sleep with incremental backoff before restarting
286
+ sleep @backoff[:delay]
282
287
 
283
- # Update increment backoff delay and retry counter
284
- @backoff[:delay] *= @backoff[:mod]
285
- @backoff[:current] += 1
288
+ # Update increment backoff delay and retry counter
289
+ @backoff[:delay] *= @backoff[:mod]
290
+ @backoff[:current] += 1
286
291
 
287
- retry
292
+ retry
293
+ end
288
294
  rescue RestartStream
289
295
  retry
290
296
  rescue StandardError => e
291
- raise Google::Cloud::Error.from_error(e)
297
+ @parent.error! e
298
+ raise e
292
299
  end
293
300
  end
294
301
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-firestore
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-06 00:00:00.000000000 Z
11
+ date: 2021-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-core
@@ -269,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
269
  - !ruby/object:Gem::Version
270
270
  version: '0'
271
271
  requirements: []
272
- rubygems_version: 3.1.3
272
+ rubygems_version: 3.1.4
273
273
  signing_key:
274
274
  specification_version: 4
275
275
  summary: API Client library for Google Cloud Firestore API