google-cloud-firestore 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/google/cloud/firestore/document_listener.rb +86 -7
- data/lib/google/cloud/firestore/document_reference.rb +1 -2
- data/lib/google/cloud/firestore/document_snapshot.rb +1 -2
- data/lib/google/cloud/firestore/query_listener.rb +82 -1
- data/lib/google/cloud/firestore/version.rb +1 -1
- data/lib/google/cloud/firestore/watch/listener.rb +23 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12a9c7f721487eef84a1d703f77f0b2f56aea624fc9c6e1052be059c49437a6f
|
4
|
+
data.tar.gz: 76d354bb9933a7a83ef6163fef5bd37da82808786f05d06a83f54dc605ca1154
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8e403df8684221a0521432017c511f8b0c4d174c97c95129f7952e6751914093fe692585127d2f0a267f9776b9a464062bd10e3f3a7d9aa7c772edcddde8d2e
|
7
|
+
data.tar.gz: bd858f3f1c199b835ce22f567068af585f9ce41d2cd9da6811f5d06bbcc45ab1aadaa40575d1684bb2245d691c90589df420343a0233039f860030513037de75
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 2.3.0 / 2020-09-30
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Add error callbacks for listener threads
|
8
|
+
* Add DocumentListener#last_error
|
9
|
+
* Add DocumentListener#on_error
|
10
|
+
* Add QueryListener#last_error
|
11
|
+
* Add QueryListener#on_error
|
12
|
+
|
3
13
|
### 2.2.0 / 2020-09-17
|
4
14
|
|
5
15
|
#### Features
|
@@ -14,11 +14,14 @@
|
|
14
14
|
|
15
15
|
|
16
16
|
require "google/cloud/firestore/watch/listener"
|
17
|
+
require "monitor"
|
17
18
|
|
18
19
|
module Google
|
19
20
|
module Cloud
|
20
21
|
module Firestore
|
21
22
|
##
|
23
|
+
# # DocumentListener
|
24
|
+
#
|
22
25
|
# An ongoing listen operation on a document reference. This is returned by
|
23
26
|
# calling {DocumentReference#listen}.
|
24
27
|
#
|
@@ -31,25 +34,28 @@ module Google
|
|
31
34
|
# nyc_ref = firestore.doc "cities/NYC"
|
32
35
|
#
|
33
36
|
# listener = nyc_ref.listen do |snapshot|
|
34
|
-
# puts "The population of #{snapshot[:name]} "
|
35
|
-
# puts "is #{snapshot[:population]}."
|
37
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
36
38
|
# end
|
37
39
|
#
|
38
40
|
# # When ready, stop the listen operation and close the stream.
|
39
41
|
# listener.stop
|
40
42
|
#
|
41
43
|
class DocumentListener
|
44
|
+
include MonitorMixin
|
42
45
|
##
|
43
46
|
# @private
|
44
47
|
# Creates the watch stream and listener object.
|
45
48
|
def initialize doc_ref, &callback
|
49
|
+
super() # to init MonitorMixin
|
50
|
+
|
46
51
|
@doc_ref = doc_ref
|
47
52
|
raise ArgumentError if @doc_ref.nil?
|
48
53
|
|
49
54
|
@callback = callback
|
50
55
|
raise ArgumentError if @callback.nil?
|
56
|
+
@error_callbacks = []
|
51
57
|
|
52
|
-
@listener = Watch::Listener.for_doc_ref doc_ref do |query_snp|
|
58
|
+
@listener = Watch::Listener.for_doc_ref self, doc_ref do |query_snp|
|
53
59
|
doc_snp = query_snp.docs.find { |doc| doc.path == @doc_ref.path }
|
54
60
|
|
55
61
|
if doc_snp.nil?
|
@@ -80,8 +86,7 @@ module Google
|
|
80
86
|
# nyc_ref = firestore.doc "cities/NYC"
|
81
87
|
#
|
82
88
|
# listener = nyc_ref.listen do |snapshot|
|
83
|
-
# puts "The population of #{snapshot[:name]} "
|
84
|
-
# puts "is #{snapshot[:population]}."
|
89
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
85
90
|
# end
|
86
91
|
#
|
87
92
|
# # When ready, stop the listen operation and close the stream.
|
@@ -103,8 +108,7 @@ module Google
|
|
103
108
|
# nyc_ref = firestore.doc "cities/NYC"
|
104
109
|
#
|
105
110
|
# listener = nyc_ref.listen do |snapshot|
|
106
|
-
# puts "The population of #{snapshot[:name]} "
|
107
|
-
# puts "is #{snapshot[:population]}."
|
111
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
108
112
|
# end
|
109
113
|
#
|
110
114
|
# # Checks if the listener is stopped.
|
@@ -119,6 +123,81 @@ module Google
|
|
119
123
|
def stopped?
|
120
124
|
@listener.stopped?
|
121
125
|
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Register to be notified of errors when raised.
|
129
|
+
#
|
130
|
+
# If an unhandled error has occurred the listener will attempt to
|
131
|
+
# recover from the error and resume listening.
|
132
|
+
#
|
133
|
+
# Multiple error handlers can be added.
|
134
|
+
#
|
135
|
+
# @yield [callback] The block to be called when an error is raised.
|
136
|
+
# @yieldparam [Exception] error The error raised.
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
# require "google/cloud/firestore"
|
140
|
+
#
|
141
|
+
# firestore = Google::Cloud::Firestore.new
|
142
|
+
#
|
143
|
+
# # Get a document reference
|
144
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
145
|
+
#
|
146
|
+
# listener = nyc_ref.listen do |snapshot|
|
147
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# # Register to be notified when unhandled errors occur.
|
151
|
+
# listener.on_error do |error|
|
152
|
+
# puts error
|
153
|
+
# end
|
154
|
+
#
|
155
|
+
# # When ready, stop the listen operation and close the stream.
|
156
|
+
# listener.stop
|
157
|
+
#
|
158
|
+
def on_error &block
|
159
|
+
raise ArgumentError, "on_error must be called with a block" unless block_given?
|
160
|
+
synchronize { @error_callbacks << block }
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# The most recent unhandled error to occur while listening for changes.
|
165
|
+
#
|
166
|
+
# If an unhandled error has occurred the listener will attempt to
|
167
|
+
# recover from the error and resume listening.
|
168
|
+
#
|
169
|
+
# @return [Exception, nil] error The most recent error raised.
|
170
|
+
#
|
171
|
+
# @example
|
172
|
+
# require "google/cloud/firestore"
|
173
|
+
#
|
174
|
+
# firestore = Google::Cloud::Firestore.new
|
175
|
+
#
|
176
|
+
# # Get a document reference
|
177
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
178
|
+
#
|
179
|
+
# listener = nyc_ref.listen do |snapshot|
|
180
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# # If an error was raised, it can be retrieved here:
|
184
|
+
# listener.last_error #=> nil
|
185
|
+
#
|
186
|
+
# # When ready, stop the listen operation and close the stream.
|
187
|
+
# listener.stop
|
188
|
+
#
|
189
|
+
def last_error
|
190
|
+
synchronize { @last_error }
|
191
|
+
end
|
192
|
+
|
193
|
+
# @private Pass the error to user-provided error callbacks.
|
194
|
+
def error! error
|
195
|
+
error_callbacks = synchronize do
|
196
|
+
@last_error = error
|
197
|
+
@error_callbacks.dup
|
198
|
+
end
|
199
|
+
error_callbacks.each { |error_callback| error_callback.call error }
|
200
|
+
end
|
122
201
|
end
|
123
202
|
end
|
124
203
|
end
|
@@ -168,8 +168,7 @@ module Google
|
|
168
168
|
# nyc_ref = firestore.doc "cities/NYC"
|
169
169
|
#
|
170
170
|
# listener = nyc_ref.listen do |snapshot|
|
171
|
-
# puts "The population of #{snapshot[:name]} "
|
172
|
-
# puts "is #{snapshot[:population]}."
|
171
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
173
172
|
# end
|
174
173
|
#
|
175
174
|
# # When ready, stop the listen operation and close the stream.
|
@@ -53,8 +53,7 @@ module Google
|
|
53
53
|
# nyc_ref = firestore.doc "cities/NYC"
|
54
54
|
#
|
55
55
|
# listener = nyc_ref.listen do |snapshot|
|
56
|
-
# puts "The population of #{snapshot[:name]} "
|
57
|
-
# puts "is #{snapshot[:population]}."
|
56
|
+
# puts "The population of #{snapshot[:name]} is #{snapshot[:population]}."
|
58
57
|
# end
|
59
58
|
#
|
60
59
|
# # When ready, stop the listen operation and close the stream.
|
@@ -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
|
@@ -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
|
-
#
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
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
|
-
|
284
|
-
|
285
|
-
|
288
|
+
# Update increment backoff delay and retry counter
|
289
|
+
@backoff[:delay] *= @backoff[:mod]
|
290
|
+
@backoff[:current] += 1
|
286
291
|
|
287
|
-
|
292
|
+
retry
|
293
|
+
end
|
288
294
|
rescue RestartStream
|
289
295
|
retry
|
290
296
|
rescue StandardError => e
|
291
|
-
|
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.
|
4
|
+
version: 2.3.0
|
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-09-
|
11
|
+
date: 2020-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-core
|