google-cloud-spanner 2.16.1 → 2.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb26c1ee1cc71cf984fecb01463a35384ee50e68cafd41399c064cc810a298f8
4
- data.tar.gz: 5d663434c4a3766acf13c3a03ef851cb81ec839a83bfd4e83340b9b5b22231f4
3
+ metadata.gz: bc70eb07f76250946af950e0dae045072c767ed0fa1be9c2f983c24f4730679a
4
+ data.tar.gz: d8faa1c37467724ed5227dcea972c0da233b56e1cf88354ff084c8394792b6ea
5
5
  SHA512:
6
- metadata.gz: f8638c29b54887f38252cc916f077d4ea5776602d331c0da853215e80b62b06fe176d6a3972b339cb650a3e936c78bab2ea2776fb0f12cc4911fd57f4c1ae33d
7
- data.tar.gz: 7bd143477dbc7b67dde5f9a9cd2a6ae6b77a5b9079117bcae3cbf3006321a3476468d79889c7bb0ffe8cca6c9de4674c7d36f8bc878430bdf6934c2b6064f645
6
+ metadata.gz: 84ceadbf10e41390c371177d5fedfb846ea83e2eabd0017b94f83a08b9ded5fff51de65f64c3cd7ee52112066593a156fb944d8b895f18665f1f90aec53dbf17
7
+ data.tar.gz: 226d5e9d43e373aa736ea58f0b4fe49ea846f995996f91448fbf387b2ba12e574c91c5bf313d37a0625324b725de46a3eee7092cbded4e23b1c6956a1674c48d
data/AUTHENTICATION.md CHANGED
@@ -32,7 +32,7 @@ client = Google::Cloud::Spanner.new
32
32
  ## Project and Credential Lookup
33
33
 
34
34
  The google-cloud-spanner library aims to make authentication
35
- as simple as possible, and provides several mechanisms to configure your system
35
+ as simple as possible and provides several mechanisms to configure your system
36
36
  without providing **Project ID** and **Service Account Credentials** directly in
37
37
  code.
38
38
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release History
2
2
 
3
+ ### 2.17.0 (2023-06-23)
4
+
5
+ #### Features
6
+
7
+ * support data_boost_enabled for partitioned query and read ([#46](https://github.com/googleapis/ruby-spanner/issues/46))
8
+
3
9
  ### 2.16.1 (2022-11-02)
4
10
 
5
11
  #### Documentation
@@ -188,6 +188,9 @@ module Google
188
188
  # * `:multiplier` (`Numeric`) - The incremental backoff multiplier.
189
189
  # * `:retry_codes` (`Array<String>`) - The error codes that should
190
190
  # trigger a retry.
191
+ # @param [Boolean] data_boost_enabled If this field is
192
+ # set `true`, the request will be executed via offline access.
193
+ # Defaults to `false`.
191
194
  #
192
195
  # @return [Array<Google::Cloud::Spanner::Partition>] The partitions
193
196
  # created by the query partition.
@@ -211,7 +214,7 @@ module Google
211
214
  #
212
215
  def partition_query sql, params: nil, types: nil,
213
216
  partition_size_bytes: nil, max_partitions: nil,
214
- query_options: nil, call_options: nil
217
+ query_options: nil, call_options: nil, data_boost_enabled: false
215
218
  ensure_session!
216
219
 
217
220
  params, types = Convert.to_input_params_and_types params, types
@@ -231,8 +234,9 @@ module Google
231
234
  param_types: types,
232
235
  transaction: tx_selector,
233
236
  partition_token: grpc.partition_token,
234
- query_options: query_options
235
- }.delete_if { |_, v| v.nil? }
237
+ query_options: query_options,
238
+ data_boost_enabled: data_boost_enabled
239
+ }.compact
236
240
  )
237
241
  Partition.from_execute_sql_grpc execute_sql_grpc
238
242
  end
@@ -277,6 +281,9 @@ module Google
277
281
  # * `:multiplier` (`Numeric`) - The incremental backoff multiplier.
278
282
  # * `:retry_codes` (`Array<String>`) - The error codes that should
279
283
  # trigger a retry.
284
+ # @param [Boolean] data_boost_enabled If this field is
285
+ # set `true`, the request will be executed via offline access.
286
+ # Defaults to `false`.
280
287
  #
281
288
  # @return [Array<Google::Cloud::Spanner::Partition>] The partitions
282
289
  # created by the read partition.
@@ -298,7 +305,7 @@ module Google
298
305
  #
299
306
  def partition_read table, columns, keys: nil, index: nil,
300
307
  partition_size_bytes: nil, max_partitions: nil,
301
- call_options: nil
308
+ call_options: nil, data_boost_enabled: false
302
309
  ensure_session!
303
310
 
304
311
  columns = Array(columns).map(&:to_s)
@@ -321,8 +328,9 @@ module Google
321
328
  key_set: keys,
322
329
  index: index,
323
330
  transaction: tx_selector,
324
- partition_token: grpc.partition_token
325
- }.delete_if { |_, v| v.nil? }
331
+ partition_token: grpc.partition_token,
332
+ data_boost_enabled: data_boost_enabled
333
+ }.compact
326
334
  )
327
335
  Partition.from_read_grpc read_grpc
328
336
  end
@@ -804,7 +812,8 @@ module Google
804
812
  transaction: partition.execute.transaction,
805
813
  partition_token: partition.execute.partition_token,
806
814
  query_options: query_options,
807
- call_options: call_options
815
+ call_options: call_options,
816
+ data_boost_enabled: partition.execute.data_boost_enabled
808
817
  end
809
818
 
810
819
  def execute_partition_read partition, call_options: nil
@@ -814,7 +823,8 @@ module Google
814
823
  index: partition.read.index,
815
824
  transaction: partition.read.transaction,
816
825
  partition_token: partition.read.partition_token,
817
- call_options: call_options
826
+ call_options: call_options,
827
+ data_boost_enabled: partition.read.data_boost_enabled
818
828
  end
819
829
  end
820
830
  end
@@ -1815,7 +1815,11 @@ module Google
1815
1815
  call_options: call_options
1816
1816
  resp = CommitResponse.from_grpc commit_resp
1817
1817
  commit_options ? resp : resp.timestamp
1818
- rescue GRPC::Aborted, Google::Cloud::AbortedError => e
1818
+ rescue GRPC::Aborted,
1819
+ Google::Cloud::AbortedError,
1820
+ GRPC::Internal,
1821
+ Google::Cloud::InternalError => e
1822
+ raise e if internal_error_and_not_retryable? e
1819
1823
  # Re-raise if deadline has passed
1820
1824
  if current_time - start_time > deadline
1821
1825
  if e.is_a? GRPC::BadStatus
@@ -2215,7 +2219,7 @@ module Google
2215
2219
  min_read_timestamp: bounded_timestamp,
2216
2220
  max_staleness: bounded_staleness,
2217
2221
  return_read_timestamp: true
2218
- }.delete_if { |_, v| v.nil? })))
2222
+ }.compact)))
2219
2223
  end
2220
2224
 
2221
2225
  def pdml_transaction session
@@ -2267,6 +2271,12 @@ module Google
2267
2271
  # Any error indicates the backoff should be handled elsewhere
2268
2272
  nil
2269
2273
  end
2274
+
2275
+ def internal_error_and_not_retryable? error
2276
+ (error.instance_of?(Google::Cloud::InternalError) ||
2277
+ error.instance_of?(GRPC::Internal)) &&
2278
+ !@project.service.retryable?(error)
2279
+ end
2270
2280
  end
2271
2281
  end
2272
2282
  end
@@ -94,7 +94,7 @@ module Google
94
94
  def upsert table, *rows
95
95
  rows = Array(rows).flatten
96
96
  return rows if rows.empty?
97
- rows.delete_if(&:nil?)
97
+ rows.compact
98
98
  rows.delete_if(&:empty?)
99
99
  @mutations += rows.map do |row|
100
100
  V1::Mutation.new(
@@ -153,7 +153,7 @@ module Google
153
153
  def insert table, *rows
154
154
  rows = Array(rows).flatten
155
155
  return rows if rows.empty?
156
- rows.delete_if(&:nil?)
156
+ rows.compact
157
157
  rows.delete_if(&:empty?)
158
158
  @mutations += rows.map do |row|
159
159
  V1::Mutation.new(
@@ -211,7 +211,7 @@ module Google
211
211
  def update table, *rows
212
212
  rows = Array(rows).flatten
213
213
  return rows if rows.empty?
214
- rows.delete_if(&:nil?)
214
+ rows.compact
215
215
  rows.delete_if(&:empty?)
216
216
  @mutations += rows.map do |row|
217
217
  V1::Mutation.new(
@@ -271,7 +271,7 @@ module Google
271
271
  def replace table, *rows
272
272
  rows = Array(rows).flatten
273
273
  return rows if rows.empty?
274
- rows.delete_if(&:nil?)
274
+ rows.compact
275
275
  rows.delete_if(&:empty?)
276
276
  @mutations += rows.map do |row|
277
277
  V1::Mutation.new(
@@ -30,8 +30,8 @@ module Google
30
30
  #
31
31
  class Pool
32
32
  attr_accessor :all_sessions
33
- attr_accessor :session_queue
34
- attr_accessor :transaction_queue
33
+ attr_accessor :session_stack
34
+ attr_accessor :transaction_stack
35
35
 
36
36
  def initialize client, min: 10, max: 100, keepalive: 1800,
37
37
  write_ratio: 0.3, fail: true, threads: nil
@@ -48,7 +48,7 @@ module Google
48
48
  @mutex = Mutex.new
49
49
  @resource = ConditionVariable.new
50
50
 
51
- # initialize pool and availability queue
51
+ # initialize pool and availability stack
52
52
  init
53
53
  end
54
54
 
@@ -69,9 +69,9 @@ module Google
69
69
 
70
70
  # Use LIFO to ensure sessions are used from backend caches, which
71
71
  # will reduce the read / write latencies on user requests.
72
- read_session = session_queue.pop # LIFO
72
+ read_session = session_stack.pop # LIFO
73
73
  return read_session if read_session
74
- write_transaction = transaction_queue.pop # LIFO
74
+ write_transaction = transaction_stack.pop # LIFO
75
75
  return write_transaction.session if write_transaction
76
76
 
77
77
  if can_allocate_more_sessions?
@@ -94,7 +94,7 @@ module Google
94
94
  raise ArgumentError, "Cannot checkin session"
95
95
  end
96
96
 
97
- session_queue.push session
97
+ session_stack.push session
98
98
 
99
99
  @resource.signal
100
100
  end
@@ -121,9 +121,9 @@ module Google
121
121
  loop do
122
122
  raise ClientClosedError if @closed
123
123
 
124
- write_transaction = transaction_queue.pop # LIFO
124
+ write_transaction = transaction_stack.pop # LIFO
125
125
  return write_transaction if write_transaction
126
- read_session = session_queue.pop
126
+ read_session = session_stack.pop
127
127
  if read_session
128
128
  action = read_session
129
129
  break
@@ -151,7 +151,7 @@ module Google
151
151
  raise ArgumentError, "Cannot checkin session"
152
152
  end
153
153
 
154
- transaction_queue.push txn
154
+ transaction_stack.push txn
155
155
 
156
156
  @resource.signal
157
157
  end
@@ -182,11 +182,11 @@ module Google
182
182
  to_release = []
183
183
 
184
184
  @mutex.synchronize do
185
- available_count = session_queue.count + transaction_queue.count
185
+ available_count = session_stack.count + transaction_stack.count
186
186
  release_count = @min - available_count
187
187
  release_count = 0 if release_count.negative?
188
188
 
189
- to_keepalive += (session_queue + transaction_queue).select do |x|
189
+ to_keepalive += (session_stack + transaction_stack).select do |x|
190
190
  x.idle_since? @keepalive
191
191
  end
192
192
 
@@ -196,8 +196,8 @@ module Google
196
196
 
197
197
  # Remove those to be released from circulation
198
198
  @all_sessions -= to_release.map(&:session)
199
- @session_queue -= to_release
200
- @transaction_queue -= to_release
199
+ @session_stack -= to_release
200
+ @transaction_stack -= to_release
201
201
  end
202
202
 
203
203
  to_release.each { |x| future { x.release! } }
@@ -210,21 +210,21 @@ module Google
210
210
  # init the thread pool
211
211
  @thread_pool = Concurrent::ThreadPoolExecutor.new \
212
212
  max_threads: @threads
213
- # init the queues
213
+ # init the stacks
214
214
  @new_sessions_in_process = 0
215
- @transaction_queue = []
215
+ @transaction_stack = []
216
216
  # init the keepalive task
217
217
  create_keepalive_task!
218
- # init session queue
218
+ # init session stack
219
219
  @all_sessions = @client.batch_create_new_sessions @min
220
220
  sessions = @all_sessions.dup
221
221
  num_transactions = (@min * @write_ratio).round
222
222
  pending_transactions = sessions.shift num_transactions
223
- # init transaction queue
223
+ # init transaction stack
224
224
  pending_transactions.each do |transaction|
225
225
  future { checkin_transaction transaction.create_transaction }
226
226
  end
227
- @session_queue = sessions
227
+ @session_stack = sessions
228
228
  end
229
229
 
230
230
  def shutdown
@@ -238,8 +238,8 @@ module Google
238
238
  @mutex.synchronize do
239
239
  @all_sessions.each { |s| future { s.release! } }
240
240
  @all_sessions = []
241
- @session_queue = []
242
- @transaction_queue = []
241
+ @session_stack = []
242
+ @transaction_stack = []
243
243
  end
244
244
  # shutdown existing thread pool
245
245
  @thread_pool.shutdown
@@ -676,7 +676,7 @@ module Google
676
676
  min: opts[:min], max: opts[:max], keepalive: opts[:keepalive],
677
677
  write_ratio: opts[:write_ratio], fail: opts[:fail],
678
678
  threads: opts[:threads]
679
- }.delete_if { |_k, v| v.nil? }
679
+ }.compact
680
680
  end
681
681
  end
682
682
  end
@@ -41,8 +41,6 @@ module Google
41
41
  # end
42
42
  #
43
43
  class Results
44
- RST_STREAM_INTERNAL_ERROR = "Received RST_STREAM".freeze
45
- EOS_INTERNAL_ERROR = "Received unexpected EOS on DATA frame from server".freeze
46
44
  ##
47
45
  # The read timestamp chosen for single-use snapshots (read-only
48
46
  # transactions).
@@ -177,7 +175,7 @@ module Google
177
175
 
178
176
  if resumable?(resume_token)
179
177
  should_resume_request = true
180
- elsif retryable?(err)
178
+ elsif @service.retryable?(err)
181
179
  should_retry_request = true
182
180
  elsif err.is_a?(Google::Cloud::Error)
183
181
  raise err
@@ -227,22 +225,6 @@ module Google
227
225
  resume_token && !resume_token.empty?
228
226
  end
229
227
 
230
- ##
231
- # @private
232
- # Checks if a request can be retried. This is based on the error returned.
233
- # Retryable errors are:
234
- # - Unavailable error
235
- # - Internal EOS error
236
- # - Internal RST_STREAM error
237
- def retryable? err
238
- err.instance_of?(Google::Cloud::UnavailableError) ||
239
- err.instance_of?(GRPC::Unavailable) ||
240
- (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(EOS_INTERNAL_ERROR)) ||
241
- (err.instance_of?(GRPC::Internal) && err.details.include?(EOS_INTERNAL_ERROR)) ||
242
- (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(RST_STREAM_INTERNAL_ERROR)) ||
243
- (err.instance_of?(GRPC::Internal) && err.details.include?(RST_STREAM_INTERNAL_ERROR))
244
- end
245
-
246
228
  ##
247
229
  # @private
248
230
  # Resumes a request, by re-executing it with a resume token.
@@ -320,13 +302,14 @@ module Google
320
302
  types: nil, transaction: nil,
321
303
  partition_token: nil, seqno: nil,
322
304
  query_options: nil, request_options: nil,
323
- call_options: nil
305
+ call_options: nil, data_boost_enabled: nil
324
306
  execute_query_options = {
325
307
  transaction: transaction, params: params, types: types,
326
308
  partition_token: partition_token, seqno: seqno,
327
309
  query_options: query_options, request_options: request_options,
328
310
  call_options: call_options
329
311
  }
312
+ execute_query_options[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
330
313
  enum = service.execute_streaming_sql session_path, sql,
331
314
  **execute_query_options
332
315
  from_enum(enum, service).tap do |results|
@@ -341,14 +324,16 @@ module Google
341
324
  def self.read service, session_path, table, columns, keys: nil,
342
325
  index: nil, limit: nil, transaction: nil,
343
326
  partition_token: nil, request_options: nil,
344
- call_options: nil
327
+ call_options: nil, data_boost_enabled: nil
345
328
  read_options = {
346
329
  keys: keys, index: index, limit: limit,
347
330
  transaction: transaction,
348
331
  partition_token: partition_token,
349
332
  request_options: request_options,
350
- call_options: call_options
333
+ call_options: call_options,
334
+ data_boost_enabled: data_boost_enabled
351
335
  }
336
+ read_options[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
352
337
  enum = service.streaming_read_table \
353
338
  session_path, table, columns, **read_options
354
339
  from_enum(enum, service).tap do |results|
@@ -36,6 +36,9 @@ module Google
36
36
  attr_accessor :lib_version
37
37
  attr_accessor :quota_project
38
38
 
39
+ RST_STREAM_INTERNAL_ERROR = "Received RST_STREAM".freeze
40
+ EOS_INTERNAL_ERROR = "Received unexpected EOS on DATA frame from server".freeze
41
+
39
42
  ##
40
43
  # Creates a new Service instance.
41
44
  def initialize project, credentials, quota_project: nil,
@@ -141,7 +144,7 @@ module Google
141
144
  display_name: name, config: instance_config_path(config),
142
145
  node_count: nodes, processing_units: processing_units,
143
146
  labels: labels
144
- }.delete_if { |_, v| v.nil? })
147
+ }.compact)
145
148
 
146
149
  request = {
147
150
  parent: project_path,
@@ -326,7 +329,7 @@ module Google
326
329
  params: nil, types: nil, resume_token: nil,
327
330
  partition_token: nil, seqno: nil,
328
331
  query_options: nil, request_options: nil,
329
- call_options: nil
332
+ call_options: nil, data_boost_enabled: nil
330
333
  opts = default_options session_name: session_name,
331
334
  call_options: call_options
332
335
  request = {
@@ -341,6 +344,7 @@ module Google
341
344
  query_options: query_options,
342
345
  request_options: request_options
343
346
  }
347
+ request[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
344
348
  service.execute_streaming_sql request, opts
345
349
  end
346
350
 
@@ -372,7 +376,8 @@ module Google
372
376
  def streaming_read_table session_name, table_name, columns, keys: nil,
373
377
  index: nil, transaction: nil, limit: nil,
374
378
  resume_token: nil, partition_token: nil,
375
- request_options: nil, call_options: nil
379
+ request_options: nil, call_options: nil,
380
+ data_boost_enabled: nil
376
381
  opts = default_options session_name: session_name,
377
382
  call_options: call_options
378
383
  request = {
@@ -381,6 +386,7 @@ module Google
381
386
  limit: limit, resume_token: resume_token,
382
387
  partition_token: partition_token, request_options: request_options
383
388
  }
389
+ request[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
384
390
  service.streaming_read request, opts
385
391
  end
386
392
 
@@ -470,7 +476,7 @@ module Google
470
476
  read_timestamp: Convert.time_to_timestamp(timestamp),
471
477
  exact_staleness: Convert.number_to_duration(staleness),
472
478
  return_read_timestamp: true
473
- }.delete_if { |_, v| v.nil? }
479
+ }.compact
474
480
  )
475
481
  )
476
482
  opts = default_options session_name: session_name,
@@ -580,6 +586,21 @@ module Google
580
586
  databases.restore_database request, opts
581
587
  end
582
588
 
589
+ ##
590
+ # Checks if a request can be retried. This is based on the error returned.
591
+ # Retryable errors are:
592
+ # - Unavailable error
593
+ # - Internal EOS error
594
+ # - Internal RST_STREAM error
595
+ def retryable? err
596
+ err.instance_of?(Google::Cloud::UnavailableError) ||
597
+ err.instance_of?(GRPC::Unavailable) ||
598
+ (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(EOS_INTERNAL_ERROR)) ||
599
+ (err.instance_of?(GRPC::Internal) && err.details.include?(EOS_INTERNAL_ERROR)) ||
600
+ (err.instance_of?(Google::Cloud::InternalError) && err.message.include?(RST_STREAM_INTERNAL_ERROR)) ||
601
+ (err.instance_of?(GRPC::Internal) && err.details.include?(RST_STREAM_INTERNAL_ERROR))
602
+ end
603
+
583
604
  def inspect
584
605
  "#{self.class}(#{@project})"
585
606
  end
@@ -338,7 +338,7 @@ module Google
338
338
  #
339
339
  def execute_query sql, params: nil, types: nil, transaction: nil,
340
340
  partition_token: nil, seqno: nil, query_options: nil,
341
- request_options: nil, call_options: nil
341
+ request_options: nil, call_options: nil, data_boost_enabled: nil
342
342
  ensure_service!
343
343
  if query_options.nil?
344
344
  query_options = @query_options
@@ -353,7 +353,8 @@ module Google
353
353
  seqno: seqno,
354
354
  query_options: query_options,
355
355
  request_options: request_options,
356
- call_options: call_options
356
+ call_options: call_options,
357
+ data_boost_enabled: data_boost_enabled
357
358
  @last_updated_at = Time.now
358
359
  results
359
360
  end
@@ -496,7 +497,7 @@ module Google
496
497
  #
497
498
  def read table, columns, keys: nil, index: nil, limit: nil,
498
499
  transaction: nil, partition_token: nil, request_options: nil,
499
- call_options: nil
500
+ call_options: nil, data_boost_enabled: nil
500
501
  ensure_service!
501
502
 
502
503
  results = Results.read service, path, table, columns,
@@ -504,7 +505,8 @@ module Google
504
505
  transaction: transaction,
505
506
  partition_token: partition_token,
506
507
  request_options: request_options,
507
- call_options: call_options
508
+ call_options: call_options,
509
+ data_boost_enabled: data_boost_enabled
508
510
  @last_updated_at = Time.now
509
511
  results
510
512
  end
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Spanner
19
- VERSION = "2.16.1".freeze
19
+ VERSION = "2.17.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-spanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.1
4
+ version: 2.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-11-02 00:00:00.000000000 Z
12
+ date: 2023-06-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -347,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
347
347
  - !ruby/object:Gem::Version
348
348
  version: '0'
349
349
  requirements: []
350
- rubygems_version: 3.3.14
350
+ rubygems_version: 3.4.2
351
351
  signing_key:
352
352
  specification_version: 4
353
353
  summary: API Client library for Google Cloud Spanner API