google-cloud-spanner 2.19.1 → 2.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cf89ec86ecf1bed2fcbec728dca49cb5b7b18c6b27b187289b80bc70cceab87
4
- data.tar.gz: 862f6429db6150c4254005fca8e0697fcda4139a1ce837c0ed88eee82e3c24f2
3
+ metadata.gz: 3b4512d4772029fbc6c9ea89195d788ddd6cb0ecb06568764ada121e37b0afe5
4
+ data.tar.gz: acd1c491242e6c656eb8cff2ad1ec09749e4895a3badb828d58eb7db98a65760
5
5
  SHA512:
6
- metadata.gz: 8d6a031a4a1af4aa914725f26fd3ff7921ab718f73df8774fd9aef5d7c419cd0d2733f5987e8d3afe54a3cb25e7bf31bf98579239fcdda4aa582ae872acea441
7
- data.tar.gz: 247ad7856b80831eb5039b8eec87a409a8c88f825dd0c65eebae40ebf9c17814870a14bcbf6316211d53cc6d1b4232b8834629c74960d4ac21b6568cd00240a5
6
+ metadata.gz: cd930852601a8ec5fb036662ad7fae03a99d5a0e9e7e566d689113d60bb62f90af4ba35da1856bdcee6a1ba147ad6f6e5a4701c37c0b59c0d371e43a25b93ec7
7
+ data.tar.gz: 7cabba248fda38947ebaf27f45b6bacf25ff14e770fcfabe76d6b66dc57c6e572aa82eb8b8bb1d4ed068036805e8f5cff56b5bc8cc553bd4921f75ac1e4a8b0d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Release History
2
2
 
3
+ ### 2.21.0 (2024-02-07)
4
+
5
+ #### Features
6
+
7
+ * support max_commit_delay for commit_options ([#85](https://github.com/googleapis/ruby-spanner/issues/85))
8
+
9
+ ### 2.20.0 (2024-01-31)
10
+
11
+ #### Features
12
+
13
+ * Support Leader Aware Routing ([#78](https://github.com/googleapis/ruby-spanner/issues/78))
14
+
3
15
  ### 2.19.1 (2024-01-24)
4
16
 
5
17
  #### Bug Fixes
@@ -24,6 +24,7 @@ require "google/cloud/spanner/range"
24
24
  require "google/cloud/spanner/column_value"
25
25
  require "google/cloud/spanner/convert"
26
26
  require "google/cloud/spanner/commit_response"
27
+ require "google/cloud/spanner/lar_headers"
27
28
 
28
29
  module Google
29
30
  module Cloud
@@ -466,12 +467,14 @@ module Google
466
467
  request_options = Convert.to_request_options request_options,
467
468
  tag_type: :request_tag
468
469
  single_use_tx = single_use_transaction single_use
470
+ route_to_leader = LARHeaders.execute_query true
469
471
  results = nil
470
472
  @pool.with_session do |session|
471
473
  results = session.execute_query \
472
474
  sql, params: params, types: types, transaction: single_use_tx,
473
475
  query_options: query_options, request_options: request_options,
474
- call_options: call_options, directed_read_options: (directed_read_options || @directed_read_options)
476
+ call_options: call_options, directed_read_options: (directed_read_options || @directed_read_options),
477
+ route_to_leader: route_to_leader
475
478
  end
476
479
  results
477
480
  end
@@ -735,14 +738,14 @@ module Google
735
738
  params, types = Convert.to_input_params_and_types params, types
736
739
  request_options = Convert.to_request_options request_options,
737
740
  tag_type: :request_tag
738
-
741
+ route_to_leader = LARHeaders.partition_query
739
742
  results = nil
740
743
  @pool.with_session do |session|
741
744
  results = session.execute_query \
742
745
  sql, params: params, types: types,
743
746
  transaction: pdml_transaction(session),
744
747
  query_options: query_options, request_options: request_options,
745
- call_options: call_options
748
+ call_options: call_options, route_to_leader: route_to_leader
746
749
  end
747
750
  # Stream all PartialResultSet to get ResultSetStats
748
751
  results.rows.to_a
@@ -956,6 +959,7 @@ module Google
956
959
  columns = Array(columns).map(&:to_s)
957
960
  keys = Convert.to_key_set keys
958
961
  single_use_tx = single_use_transaction single_use
962
+ route_to_leader = LARHeaders.read false
959
963
  request_options = Convert.to_request_options request_options,
960
964
  tag_type: :request_tag
961
965
 
@@ -966,7 +970,8 @@ module Google
966
970
  transaction: single_use_tx,
967
971
  request_options: request_options,
968
972
  call_options: call_options,
969
- directed_read_options: (directed_read_options || @directed_read_options)
973
+ directed_read_options: (directed_read_options || @directed_read_options),
974
+ route_to_leader: route_to_leader
970
975
  end
971
976
  results
972
977
  end
@@ -1017,6 +1022,10 @@ module Google
1017
1022
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1018
1023
  # then statistics related to the transaction will be included in
1019
1024
  # {CommitResponse}. Default value is `false`
1025
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1026
+ # is willing to incur in order to improve throughput.
1027
+ # The commit delay must be at least 0ms and at most 500ms.
1028
+ # Default value is nil.
1020
1029
  # @param [Hash] request_options Common request options.
1021
1030
  #
1022
1031
  # * `:priority` (String) The relative priority for requests.
@@ -1136,6 +1145,10 @@ module Google
1136
1145
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1137
1146
  # then statistics related to the transaction will be included in
1138
1147
  # {CommitResponse}. Default value is `false`
1148
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1149
+ # is willing to incur in order to improve throughput.
1150
+ # The commit delay must be at least 0ms and at most 500ms.
1151
+ # Default value is nil.
1139
1152
  # @param [Hash] request_options Common request options.
1140
1153
  #
1141
1154
  # * `:priority` (String) The relative priority for requests.
@@ -1254,6 +1267,10 @@ module Google
1254
1267
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1255
1268
  # then statistics related to the transaction will be included in
1256
1269
  # {CommitResponse}. Default value is `false`
1270
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1271
+ # is willing to incur in order to improve throughput.
1272
+ # The commit delay must be at least 0ms and at most 500ms.
1273
+ # Default value is nil.
1257
1274
  # @param [Hash] request_options Common request options.
1258
1275
  #
1259
1276
  # * `:priority` (String) The relative priority for requests.
@@ -1373,6 +1390,10 @@ module Google
1373
1390
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1374
1391
  # then statistics related to the transaction will be included in
1375
1392
  # {CommitResponse}. Default value is `false`
1393
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1394
+ # is willing to incur in order to improve throughput.
1395
+ # The commit delay must be at least 0ms and at most 500ms.
1396
+ # Default value is nil.
1376
1397
  # @param [Hash] request_options Common request options.
1377
1398
  #
1378
1399
  # * `:priority` (String) The relative priority for requests.
@@ -1470,6 +1491,10 @@ module Google
1470
1491
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1471
1492
  # then statistics related to the transaction will be included in
1472
1493
  # {CommitResponse}. Default value is `false`
1494
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1495
+ # is willing to incur in order to improve throughput.
1496
+ # The commit delay must be at least 0ms and at most 500ms.
1497
+ # Default value is nil.
1473
1498
  # @param [Hash] request_options Common request options.
1474
1499
  #
1475
1500
  # * `:priority` (String) The relative priority for requests.
@@ -1574,6 +1599,10 @@ module Google
1574
1599
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1575
1600
  # then statistics related to the transaction will be included in
1576
1601
  # {CommitResponse}. Default value is `false`
1602
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1603
+ # is willing to incur in order to improve throughput.
1604
+ # The commit delay must be at least 0ms and at most 500ms.
1605
+ # Default value is nil.
1577
1606
  # @param [Hash] request_options Common request options.
1578
1607
  #
1579
1608
  # * `:priority` (String) The relative priority for requests.
@@ -1701,6 +1730,10 @@ module Google
1701
1730
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1702
1731
  # then statistics related to the transaction will be included in
1703
1732
  # {CommitResponse}. Default value is `false`
1733
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1734
+ # is willing to incur in order to improve throughput.
1735
+ # The commit delay must be at least 0ms and at most 500ms.
1736
+ # Default value is nil.
1704
1737
  # @param [Hash] request_options Common request options.
1705
1738
  #
1706
1739
  # * `:priority` (String) The relative priority for requests.
@@ -242,8 +242,9 @@ module Google
242
242
  Hash[row_to_pairs(row_types, row)]
243
243
  end
244
244
 
245
- def number_to_duration number
245
+ def number_to_duration number, millisecond: false
246
246
  return nil if number.nil?
247
+ number = number/1000.to_f if millisecond
247
248
 
248
249
  Google::Protobuf::Duration.new \
249
250
  seconds: number.to_i,
@@ -0,0 +1,100 @@
1
+ # Copyright 2024 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Spanner
19
+ ##
20
+ # @private Helper module to access header values
21
+ # for Leader Aware Routing (LAR).
22
+ #
23
+ # For a multi-region Cloud Spanner instance, the majority of
24
+ # the write latency is attributed to the network round trip
25
+ # caused by several RPCs between SpanFE and SpanServer. This
26
+ # latency is amplified when the client application is deployed
27
+ # away from the leader region.
28
+ #
29
+ # To decrease the latency, we use LAR to help Google Front End (GFE)
30
+ # or Cloudpath Front End (CFE) to route requests directly to the
31
+ # leader region or the nearest non-leader region.
32
+ #
33
+ # For every RPC, we pass the header `x-goog-spanner-route-to-leader`,
34
+ # whose value is either 'true' or 'false'. Some RPCs (such as admin APIs)
35
+ # don't pass the header since they're deprecated in the handwritten
36
+ # client. Also, users of the client can choose to opt out of the
37
+ # LAR feature, in which case, we don't pass the header.
38
+ #
39
+ # This module lists the header values for different RPCs to be used
40
+ # by the client. These values are expected to be constant. Some RPCs
41
+ # (such as `execute_streaming_sql`) can have different values
42
+ # depending on whether they're run within read-only transactions
43
+ # or read-write transactions.
44
+ #
45
+ module LARHeaders
46
+ class << self
47
+ def begin_transaction is_read_write_tx
48
+ is_read_write_tx ? "true" : "false"
49
+ end
50
+
51
+ def read is_read_write_tx
52
+ is_read_write_tx ? "true" : "false"
53
+ end
54
+
55
+ def execute_query is_read_write_tx
56
+ is_read_write_tx ? "true" : "false"
57
+ end
58
+
59
+ def commit
60
+ "true"
61
+ end
62
+
63
+ def execute_batch_dml
64
+ "true"
65
+ end
66
+
67
+ def create_session
68
+ "true"
69
+ end
70
+
71
+ def batch_create_sessions
72
+ "true"
73
+ end
74
+
75
+ def delete_session
76
+ "false"
77
+ end
78
+
79
+ # rubocop:disable Naming/AccessorMethodName
80
+ def get_session
81
+ "true"
82
+ end
83
+ # rubocop:enable Naming/AccessorMethodName
84
+
85
+ def partition_read
86
+ "true"
87
+ end
88
+
89
+ def partition_query
90
+ "true"
91
+ end
92
+
93
+ def rollback
94
+ "true"
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -20,6 +20,7 @@ require "google/cloud/spanner/v1"
20
20
  require "google/cloud/spanner/admin/instance/v1"
21
21
  require "google/cloud/spanner/admin/database/v1"
22
22
  require "google/cloud/spanner/convert"
23
+ require "google/cloud/spanner/lar_headers"
23
24
 
24
25
  module Google
25
26
  module Cloud
@@ -35,6 +36,7 @@ module Google
35
36
  attr_accessor :lib_name
36
37
  attr_accessor :lib_version
37
38
  attr_accessor :quota_project
39
+ attr_accessor :enable_leader_aware_routing
38
40
 
39
41
  RST_STREAM_INTERNAL_ERROR = "Received RST_STREAM".freeze
40
42
  EOS_INTERNAL_ERROR = "Received unexpected EOS on DATA frame from server".freeze
@@ -42,7 +44,8 @@ module Google
42
44
  ##
43
45
  # Creates a new Service instance.
44
46
  def initialize project, credentials, quota_project: nil,
45
- host: nil, timeout: nil, lib_name: nil, lib_version: nil
47
+ host: nil, timeout: nil, lib_name: nil, lib_version: nil,
48
+ enable_leader_aware_routing: nil
46
49
  @project = project
47
50
  @credentials = credentials
48
51
  @quota_project = quota_project || (credentials.quota_project_id if credentials.respond_to? :quota_project_id)
@@ -50,6 +53,7 @@ module Google
50
53
  @timeout = timeout
51
54
  @lib_name = lib_name
52
55
  @lib_version = lib_version
56
+ @enable_leader_aware_routing = enable_leader_aware_routing
53
57
  end
54
58
 
55
59
  def channel
@@ -290,15 +294,19 @@ module Google
290
294
  end
291
295
 
292
296
  def get_session session_name, call_options: nil
297
+ route_to_leader = LARHeaders.get_session
293
298
  opts = default_options session_name: session_name,
294
- call_options: call_options
299
+ call_options: call_options,
300
+ route_to_leader: route_to_leader
295
301
  service.get_session({ name: session_name }, opts)
296
302
  end
297
303
 
298
304
  def create_session database_name, labels: nil,
299
305
  call_options: nil, database_role: nil
306
+ route_to_leader = LARHeaders.create_session
300
307
  opts = default_options session_name: database_name,
301
- call_options: call_options
308
+ call_options: call_options,
309
+ route_to_leader: route_to_leader
302
310
  session = V1::Session.new labels: labels, creator_role: database_role if labels || database_role
303
311
  service.create_session(
304
312
  { database: database_name, session: session }, opts
@@ -307,8 +315,10 @@ module Google
307
315
 
308
316
  def batch_create_sessions database_name, session_count, labels: nil,
309
317
  call_options: nil, database_role: nil
318
+ route_to_leader = LARHeaders.batch_create_sessions
310
319
  opts = default_options session_name: database_name,
311
- call_options: call_options
320
+ call_options: call_options,
321
+ route_to_leader: route_to_leader
312
322
  session = V1::Session.new labels: labels, creator_role: database_role if labels || database_role
313
323
  # The response may have fewer sessions than requested in the RPC.
314
324
  request = {
@@ -320,8 +330,10 @@ module Google
320
330
  end
321
331
 
322
332
  def delete_session session_name, call_options: nil
333
+ route_to_leader = LARHeaders.delete_session
323
334
  opts = default_options session_name: session_name,
324
- call_options: call_options
335
+ call_options: call_options,
336
+ route_to_leader: route_to_leader
325
337
  service.delete_session({ name: session_name }, opts)
326
338
  end
327
339
 
@@ -330,9 +342,11 @@ module Google
330
342
  partition_token: nil, seqno: nil,
331
343
  query_options: nil, request_options: nil,
332
344
  call_options: nil, data_boost_enabled: nil,
333
- directed_read_options: nil
345
+ directed_read_options: nil,
346
+ route_to_leader: nil
334
347
  opts = default_options session_name: session_name,
335
- call_options: call_options
348
+ call_options: call_options,
349
+ route_to_leader: route_to_leader
336
350
  request = {
337
351
  session: session_name,
338
352
  sql: sql,
@@ -352,8 +366,10 @@ module Google
352
366
 
353
367
  def execute_batch_dml session_name, transaction, statements, seqno,
354
368
  request_options: nil, call_options: nil
369
+ route_to_leader = LARHeaders.execute_batch_dml
355
370
  opts = default_options session_name: session_name,
356
- call_options: call_options
371
+ call_options: call_options,
372
+ route_to_leader: route_to_leader
357
373
  statements = statements.map(&:to_grpc)
358
374
  request = {
359
375
  session: session_name,
@@ -369,9 +385,11 @@ module Google
369
385
  index: nil, transaction: nil, limit: nil,
370
386
  resume_token: nil, partition_token: nil,
371
387
  request_options: nil, call_options: nil,
372
- data_boost_enabled: nil, directed_read_options: nil
388
+ data_boost_enabled: nil, directed_read_options: nil,
389
+ route_to_leader: nil
373
390
  opts = default_options session_name: session_name,
374
- call_options: call_options
391
+ call_options: call_options,
392
+ route_to_leader: route_to_leader
375
393
  request = {
376
394
  session: session_name, table: table_name, columns: columns,
377
395
  key_set: keys, transaction: transaction, index: index,
@@ -388,9 +406,10 @@ module Google
388
406
  max_partitions: nil, call_options: nil
389
407
  partition_opts = partition_options partition_size_bytes,
390
408
  max_partitions
391
-
409
+ route_to_leader = LARHeaders.partition_read
392
410
  opts = default_options session_name: session_name,
393
- call_options: call_options
411
+ call_options: call_options,
412
+ route_to_leader: route_to_leader
394
413
  request = {
395
414
  session: session_name, table: table_name, key_set: keys,
396
415
  transaction: transaction, index: index, columns: columns,
@@ -404,9 +423,10 @@ module Google
404
423
  max_partitions: nil, call_options: nil
405
424
  partition_opts = partition_options partition_size_bytes,
406
425
  max_partitions
407
-
426
+ route_to_leader = LARHeaders.partition_query
408
427
  opts = default_options session_name: session_name,
409
- call_options: call_options
428
+ call_options: call_options,
429
+ route_to_leader: route_to_leader
410
430
  request = {
411
431
  session: session_name, sql: sql, transaction: transaction,
412
432
  params: params, param_types: types,
@@ -417,6 +437,7 @@ module Google
417
437
 
418
438
  def commit session_name, mutations = [], transaction_id: nil,
419
439
  commit_options: nil, request_options: nil, call_options: nil
440
+ route_to_leader = LARHeaders.commit
420
441
  tx_opts = nil
421
442
  if transaction_id.nil?
422
443
  tx_opts = V1::TransactionOptions.new(
@@ -424,34 +445,52 @@ module Google
424
445
  )
425
446
  end
426
447
  opts = default_options session_name: session_name,
427
- call_options: call_options
448
+ call_options: call_options,
449
+ route_to_leader: route_to_leader
428
450
  request = {
429
451
  session: session_name, transaction_id: transaction_id,
430
452
  single_use_transaction: tx_opts, mutations: mutations,
431
453
  request_options: request_options
432
454
  }
433
455
 
434
- if commit_options
435
- request[:return_commit_stats] = commit_options[:return_commit_stats]
436
- end
456
+ request = add_commit_options request, commit_options
437
457
 
438
458
  service.commit request, opts
439
459
  end
440
460
 
461
+ def add_commit_options request, commit_options
462
+ if commit_options
463
+ if commit_options.key? :return_commit_stats
464
+ request[:return_commit_stats] =
465
+ commit_options[:return_commit_stats]
466
+ end
467
+ if commit_options.key? :max_commit_delay
468
+ request[:max_commit_delay] =
469
+ Convert.number_to_duration(commit_options[:max_commit_delay],
470
+ millisecond: true)
471
+ end
472
+ end
473
+ request
474
+ end
475
+
441
476
  def rollback session_name, transaction_id, call_options: nil
477
+ route_to_leader = LARHeaders.rollback
442
478
  opts = default_options session_name: session_name,
443
- call_options: call_options
479
+ call_options: call_options,
480
+ route_to_leader: route_to_leader
444
481
  request = { session: session_name, transaction_id: transaction_id }
445
482
  service.rollback request, opts
446
483
  end
447
484
 
448
485
  def begin_transaction session_name, request_options: nil,
449
- call_options: nil
486
+ call_options: nil,
487
+ route_to_leader: nil
450
488
  tx_opts = V1::TransactionOptions.new(
451
489
  read_write: V1::TransactionOptions::ReadWrite.new
452
490
  )
453
491
  opts = default_options session_name: session_name,
454
- call_options: call_options
492
+ call_options: call_options,
493
+ route_to_leader: route_to_leader
455
494
  request = {
456
495
  session: session_name,
457
496
  options: tx_opts,
@@ -482,8 +521,10 @@ module Google
482
521
  tx_opts = V1::TransactionOptions.new(
483
522
  partitioned_dml: V1::TransactionOptions::PartitionedDml.new
484
523
  )
524
+ route_to_leader = LARHeaders.begin_transaction true
485
525
  opts = default_options session_name: session_name,
486
- call_options: call_options
526
+ call_options: call_options,
527
+ route_to_leader: route_to_leader
487
528
  request = { session: session_name, options: tx_opts }
488
529
  service.begin_transaction request, opts
489
530
  end
@@ -608,12 +649,17 @@ module Google
608
649
  value << " gccl"
609
650
  end
610
651
 
611
- def default_options session_name: nil, call_options: nil
652
+ def default_options session_name: nil, call_options: nil, route_to_leader: nil
612
653
  opts = {}
654
+ metadata = {}
613
655
  if session_name
614
656
  default_prefix = session_name.split("/sessions/").first
615
- opts[:metadata] = { "google-cloud-resource-prefix" => default_prefix }
657
+ metadata["google-cloud-resource-prefix"] = default_prefix
658
+ end
659
+ if @enable_leader_aware_routing && !route_to_leader.nil?
660
+ metadata["x-goog-spanner-route-to-leader"] = route_to_leader
616
661
  end
662
+ opts[:metadata] = metadata
617
663
  if call_options
618
664
  opts[:timeout] = call_options[:timeout] if call_options[:timeout]
619
665
  opts[:retry_policy] = call_options[:retry_policy] if call_options[:retry_policy]
@@ -339,7 +339,7 @@ module Google
339
339
  def execute_query sql, params: nil, types: nil, transaction: nil,
340
340
  partition_token: nil, seqno: nil, query_options: nil,
341
341
  request_options: nil, call_options: nil, data_boost_enabled: nil,
342
- directed_read_options: nil
342
+ directed_read_options: nil, route_to_leader: nil
343
343
  ensure_service!
344
344
  query_options = merge_if_present query_options, @query_options
345
345
 
@@ -347,7 +347,8 @@ module Google
347
347
  transaction: transaction, params: params, types: types,
348
348
  partition_token: partition_token, seqno: seqno,
349
349
  query_options: query_options, request_options: request_options,
350
- call_options: call_options
350
+ call_options: call_options,
351
+ route_to_leader: route_to_leader
351
352
  }
352
353
  execute_query_options[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
353
354
  execute_query_options[:directed_read_options] = directed_read_options unless directed_read_options.nil?
@@ -497,7 +498,8 @@ module Google
497
498
  #
498
499
  def read table, columns, keys: nil, index: nil, limit: nil,
499
500
  transaction: nil, partition_token: nil, request_options: nil,
500
- call_options: nil, data_boost_enabled: nil, directed_read_options: nil
501
+ call_options: nil, data_boost_enabled: nil, directed_read_options: nil,
502
+ route_to_leader: nil
501
503
  ensure_service!
502
504
 
503
505
  read_options = {
@@ -505,7 +507,8 @@ module Google
505
507
  transaction: transaction,
506
508
  partition_token: partition_token,
507
509
  request_options: request_options,
508
- call_options: call_options
510
+ call_options: call_options,
511
+ route_to_leader: route_to_leader
509
512
  }
510
513
  read_options[:data_boost_enabled] = data_boost_enabled unless data_boost_enabled.nil?
511
514
  read_options[:directed_read_options] = directed_read_options unless directed_read_options.nil?
@@ -566,8 +569,11 @@ module Google
566
569
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
567
570
  # then statistics related to the transaction will be included in
568
571
  # {CommitResponse}. Default value is `false`
572
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
573
+ # is willing to incur in order to improve throughput.
574
+ # The commit delay must be at least 0ms and at most 500ms.
575
+ # Default value is nil.
569
576
  #
570
- # transaction. Default it is `false`.
571
577
  # @param [Hash] request_options Common request options.
572
578
  #
573
579
  # * `:request_tag` (String) A per-request tag which can be applied
@@ -683,7 +689,10 @@ module Google
683
689
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
684
690
  # then statistics related to the transaction will be included in
685
691
  # {CommitResponse}. Default value is `false`
686
- #
692
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
693
+ # is willing to incur in order to improve throughput.
694
+ # The commit delay must be at least 0ms and at most 500ms.
695
+ # Default value is nil.
687
696
  # @param [Hash] request_options Common request options.
688
697
  #
689
698
  # * `:request_tag` (String) A per-request tag which can be applied
@@ -791,7 +800,10 @@ module Google
791
800
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
792
801
  # then statistics related to the transaction will be included in
793
802
  # {CommitResponse}. Default value is `false`
794
- #
803
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
804
+ # is willing to incur in order to improve throughput.
805
+ # The commit delay must be at least 0ms and at most 500ms.
806
+ # Default value is nil.
795
807
  # @param [Hash] request_options Common request options.
796
808
  #
797
809
  # * `:request_tag` (String) A per-request tag which can be applied
@@ -898,7 +910,10 @@ module Google
898
910
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
899
911
  # then statistics related to the transaction will be included in
900
912
  # {CommitResponse}. Default value is `false`
901
- #
913
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
914
+ # is willing to incur in order to improve throughput.
915
+ # The commit delay must be at least 0ms and at most 500ms.
916
+ # Default value is nil.
902
917
  # @param [Hash] request_options Common request options.
903
918
  #
904
919
  # * `:request_tag` (String) A per-request tag which can be applied
@@ -1006,7 +1021,11 @@ module Google
1006
1021
  #
1007
1022
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1008
1023
  # then statistics related to the transaction will be included in
1009
- # {CommitResponse}. Default value is `false`.
1024
+ # {CommitResponse}. Default value is `false`
1025
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1026
+ # is willing to incur in order to improve throughput.
1027
+ # The commit delay must be at least 0ms and at most 500ms.
1028
+ # Default value is nil.
1010
1029
  #
1011
1030
  # @param [Hash] request_options Common request options.
1012
1031
  #
@@ -1096,7 +1115,10 @@ module Google
1096
1115
  # * `:return_commit_stats` (Boolean) A boolean value. If `true`,
1097
1116
  # then statistics related to the transaction will be included in
1098
1117
  # {CommitResponse}. Default value is `false`
1099
- #
1118
+ # * `:maxCommitDelay` (Numeric) The amount of latency in millisecond in this request
1119
+ # is willing to incur in order to improve throughput.
1120
+ # The commit delay must be at least 0ms and at most 500ms.
1121
+ # Default value is nil.
1100
1122
  # @param [Hash] request_options Common request options.
1101
1123
  #
1102
1124
  # * `:request_tag` (String) A per-request tag which can be applied
@@ -1178,7 +1200,8 @@ module Google
1178
1200
  # @private
1179
1201
  # Creates a new transaction object every time.
1180
1202
  def create_transaction
1181
- tx_grpc = service.begin_transaction path
1203
+ route_to_leader = LARHeaders.begin_transaction true
1204
+ tx_grpc = service.begin_transaction path, route_to_leader: route_to_leader
1182
1205
  Transaction.from_grpc tx_grpc, self
1183
1206
  end
1184
1207
 
@@ -1214,7 +1237,8 @@ module Google
1214
1237
  # Keeps the session alive by executing `"SELECT 1"`.
1215
1238
  def keepalive!
1216
1239
  ensure_service!
1217
- execute_query "SELECT 1"
1240
+ route_to_leader = LARHeaders.execute_query false
1241
+ execute_query "SELECT 1", route_to_leader: route_to_leader
1218
1242
  true
1219
1243
  rescue Google::Cloud::NotFoundError
1220
1244
  labels = @grpc.labels.to_h unless @grpc.labels.to_h.empty?
@@ -18,6 +18,7 @@ require "google/cloud/spanner/convert"
18
18
  require "google/cloud/spanner/results"
19
19
  require "google/cloud/spanner/commit"
20
20
  require "google/cloud/spanner/batch_update_results"
21
+ require "google/cloud/spanner/lar_headers"
21
22
 
22
23
  module Google
23
24
  module Cloud
@@ -361,13 +362,15 @@ module Google
361
362
 
362
363
  params, types = Convert.to_input_params_and_types params, types
363
364
  request_options = build_request_options request_options
365
+ route_to_leader = LARHeaders.execute_query true
364
366
 
365
367
  safe_execute do |seqno|
366
368
  results = session.execute_query sql, params: params, types: types,
367
369
  transaction: tx_selector, seqno: seqno,
368
370
  query_options: query_options,
369
371
  request_options: request_options,
370
- call_options: call_options
372
+ call_options: call_options,
373
+ route_to_leader: route_to_leader
371
374
  @grpc ||= results.transaction
372
375
  results
373
376
  end
@@ -715,12 +718,14 @@ module Google
715
718
  columns = Array(columns).map(&:to_s)
716
719
  keys = Convert.to_key_set keys
717
720
  request_options = build_request_options request_options
721
+ route_to_leader = LARHeaders.read true
718
722
 
719
723
  safe_execute do
720
724
  results = session.read table, columns, keys: keys, index: index, limit: limit,
721
725
  transaction: tx_selector,
722
726
  request_options: request_options,
723
- call_options: call_options
727
+ call_options: call_options,
728
+ route_to_leader: route_to_leader
724
729
  @grpc ||= results.transaction
725
730
  results
726
731
  end
@@ -1190,7 +1195,8 @@ module Google
1190
1195
  @mutex.synchronize do
1191
1196
  return if existing_transaction?
1192
1197
  ensure_session!
1193
- @grpc = service.begin_transaction session.path
1198
+ route_to_leader = LARHeaders.begin_transaction true
1199
+ @grpc = service.begin_transaction session.path, route_to_leader: route_to_leader
1194
1200
  end
1195
1201
  end
1196
1202
 
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Spanner
19
- VERSION = "2.19.1".freeze
19
+ VERSION = "2.21.0".freeze
20
20
  end
21
21
  end
22
22
  end
@@ -82,6 +82,8 @@ module Google
82
82
  # `spanner-activerecord/0.0.1` is provided custom library name and
83
83
  # version and `gccl/1.13.1` represents the Cloud Spanner Ruby library
84
84
  # with version.
85
+ # @param enable_leader_aware_routing [Boolean] Specifies whether Leader
86
+ # Aware Routing should be enabled. Defaults to true.
85
87
  #
86
88
  # @return [Google::Cloud::Spanner::Project]
87
89
  #
@@ -92,7 +94,8 @@ module Google
92
94
  #
93
95
  def self.new project_id: nil, credentials: nil, scope: nil, timeout: nil,
94
96
  endpoint: nil, project: nil, keyfile: nil,
95
- emulator_host: nil, lib_name: nil, lib_version: nil
97
+ emulator_host: nil, lib_name: nil, lib_version: nil,
98
+ enable_leader_aware_routing: true
96
99
  project_id ||= project || default_project_id
97
100
  scope ||= configure.scope
98
101
  timeout ||= configure.timeout
@@ -122,7 +125,8 @@ module Google
122
125
  Spanner::Service.new(
123
126
  project_id, credentials, quota_project: configure.quota_project,
124
127
  host: endpoint, timeout: timeout, lib_name: lib_name,
125
- lib_version: lib_version
128
+ lib_version: lib_version,
129
+ enable_leader_aware_routing: enable_leader_aware_routing
126
130
  ),
127
131
  query_options: configure.query_options
128
132
  )
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.19.1
4
+ version: 2.21.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: 2024-01-24 00:00:00.000000000 Z
12
+ date: 2024-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -317,6 +317,7 @@ files:
317
317
  - lib/google/cloud/spanner/instance/config/list.rb
318
318
  - lib/google/cloud/spanner/instance/job.rb
319
319
  - lib/google/cloud/spanner/instance/list.rb
320
+ - lib/google/cloud/spanner/lar_headers.rb
320
321
  - lib/google/cloud/spanner/partition.rb
321
322
  - lib/google/cloud/spanner/policy.rb
322
323
  - lib/google/cloud/spanner/pool.rb