google-cloud-spanner 2.29.0 → 2.31.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 +12 -0
- data/lib/google/cloud/spanner/backup/job.rb +3 -1
- data/lib/google/cloud/spanner/batch_client.rb +17 -8
- data/lib/google/cloud/spanner/batch_snapshot.rb +18 -4
- data/lib/google/cloud/spanner/batch_update_results.rb +7 -2
- data/lib/google/cloud/spanner/client.rb +135 -92
- data/lib/google/cloud/spanner/commit.rb +3 -0
- data/lib/google/cloud/spanner/commit_response.rb +11 -5
- data/lib/google/cloud/spanner/instance.rb +2 -2
- data/lib/google/cloud/spanner/pool.rb +65 -6
- data/lib/google/cloud/spanner/project.rb +8 -22
- data/lib/google/cloud/spanner/results.rb +51 -16
- data/lib/google/cloud/spanner/service.rb +76 -12
- data/lib/google/cloud/spanner/session.rb +121 -52
- data/lib/google/cloud/spanner/session_cache.rb +125 -0
- data/lib/google/cloud/spanner/session_creation_options.rb +70 -0
- data/lib/google/cloud/spanner/snapshot.rb +29 -9
- data/lib/google/cloud/spanner/transaction.rb +124 -36
- data/lib/google/cloud/spanner/version.rb +1 -1
- metadata +3 -1
|
@@ -44,8 +44,8 @@ module Google
|
|
|
44
44
|
#
|
|
45
45
|
class Session
|
|
46
46
|
# The wrapped `V1::Session` protobuf session object.
|
|
47
|
-
# @return [::Google::Cloud::Spanner::V1::Session]
|
|
48
47
|
# @private
|
|
48
|
+
# @return [::Google::Cloud::Spanner::V1::Session]
|
|
49
49
|
attr_accessor :grpc
|
|
50
50
|
|
|
51
51
|
# The `Spanner::Service` object.
|
|
@@ -59,7 +59,7 @@ module Google
|
|
|
59
59
|
# @return [::Hash, nil]
|
|
60
60
|
attr_accessor :query_options
|
|
61
61
|
|
|
62
|
-
# Creates a new Session instance.
|
|
62
|
+
# Creates a new `Spanner::Session` instance.
|
|
63
63
|
# @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
|
|
64
64
|
# @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` object.
|
|
65
65
|
# @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
|
|
@@ -69,6 +69,7 @@ module Google
|
|
|
69
69
|
@grpc = grpc
|
|
70
70
|
@service = service
|
|
71
71
|
@query_options = query_options
|
|
72
|
+
@created_time = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
72
73
|
end
|
|
73
74
|
|
|
74
75
|
# The unique identifier for the project.
|
|
@@ -216,6 +217,9 @@ module Google
|
|
|
216
217
|
# * `:retry_codes` (`Array<String>`) - The error codes that should
|
|
217
218
|
# trigger a retry.
|
|
218
219
|
#
|
|
220
|
+
# @param precommit_token_notify [::Proc, nil] Optional.
|
|
221
|
+
# The notification function for the precommit token.
|
|
222
|
+
#
|
|
219
223
|
# @return [Google::Cloud::Spanner::Results] The results of the query
|
|
220
224
|
# execution.
|
|
221
225
|
#
|
|
@@ -357,7 +361,8 @@ module Google
|
|
|
357
361
|
def execute_query sql, params: nil, types: nil, transaction: nil,
|
|
358
362
|
partition_token: nil, seqno: nil, query_options: nil,
|
|
359
363
|
request_options: nil, call_options: nil, data_boost_enabled: nil,
|
|
360
|
-
directed_read_options: nil, route_to_leader: nil
|
|
364
|
+
directed_read_options: nil, route_to_leader: nil,
|
|
365
|
+
precommit_token_notify: nil
|
|
361
366
|
ensure_service!
|
|
362
367
|
query_options = merge_if_present query_options, @query_options
|
|
363
368
|
|
|
@@ -373,7 +378,8 @@ module Google
|
|
|
373
378
|
|
|
374
379
|
response = service.execute_streaming_sql path, sql, **execute_query_options
|
|
375
380
|
|
|
376
|
-
results = Results.from_execute_query_response response, service, path, sql, execute_query_options
|
|
381
|
+
results = Results.from_execute_query_response response, service, path, sql, execute_query_options,
|
|
382
|
+
precommit_token_notify: precommit_token_notify
|
|
377
383
|
@last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
378
384
|
results
|
|
379
385
|
end
|
|
@@ -428,8 +434,8 @@ module Google
|
|
|
428
434
|
# number of rows that were modified for each successful statement
|
|
429
435
|
# before the error.
|
|
430
436
|
#
|
|
431
|
-
# @return [
|
|
432
|
-
#
|
|
437
|
+
# @return [::Google::Cloud::Spanner::V1::ExecuteBatchDmlResponse]
|
|
438
|
+
# An unwrapped result of the service call -- a `V1::ExecuteBatchDmlResponse` object.
|
|
433
439
|
#
|
|
434
440
|
def batch_update transaction, seqno, request_options: nil,
|
|
435
441
|
call_options: nil
|
|
@@ -506,6 +512,9 @@ module Google
|
|
|
506
512
|
# To see the available options refer to
|
|
507
513
|
# ['Google::Cloud::Spanner::V1::ReadRequest::LockHint'](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-LockHint)
|
|
508
514
|
#
|
|
515
|
+
# @param precommit_token_notify [::Proc, nil] Optional.
|
|
516
|
+
# The notification function for the precommit token.
|
|
517
|
+
#
|
|
509
518
|
# @return [Google::Cloud::Spanner::Results] The results of the read
|
|
510
519
|
# operation.
|
|
511
520
|
#
|
|
@@ -525,7 +534,7 @@ module Google
|
|
|
525
534
|
def read table, columns, keys: nil, index: nil, limit: nil,
|
|
526
535
|
transaction: nil, partition_token: nil, request_options: nil,
|
|
527
536
|
call_options: nil, data_boost_enabled: nil, directed_read_options: nil,
|
|
528
|
-
route_to_leader: nil, order_by: nil, lock_hint: nil
|
|
537
|
+
route_to_leader: nil, order_by: nil, lock_hint: nil, precommit_token_notify: nil
|
|
529
538
|
ensure_service!
|
|
530
539
|
|
|
531
540
|
read_options = {
|
|
@@ -544,7 +553,8 @@ module Google
|
|
|
544
553
|
response = service.streaming_read_table \
|
|
545
554
|
path, table, columns, **read_options
|
|
546
555
|
|
|
547
|
-
results = Results.from_read_response response, service, path, table, columns, read_options
|
|
556
|
+
results = Results.from_read_response response, service, path, table, columns, read_options,
|
|
557
|
+
precommit_token_notify: precommit_token_notify
|
|
548
558
|
|
|
549
559
|
@last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
550
560
|
|
|
@@ -593,6 +603,8 @@ module Google
|
|
|
593
603
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
594
604
|
# mutations will not be recorded in change streams with DDL option
|
|
595
605
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
606
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
607
|
+
# isolation level for the transaction.
|
|
596
608
|
# @param [Hash] commit_options A hash of commit options.
|
|
597
609
|
# e.g., return_commit_stats. Commit options are optional.
|
|
598
610
|
# The following options can be provided:
|
|
@@ -671,16 +683,30 @@ module Google
|
|
|
671
683
|
# puts commit_resp.stats.mutation_count
|
|
672
684
|
#
|
|
673
685
|
def commit transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
674
|
-
|
|
686
|
+
isolation_level: nil, commit_options: nil, request_options: nil,
|
|
687
|
+
call_options: nil
|
|
675
688
|
ensure_service!
|
|
676
689
|
commit = Commit.new
|
|
677
690
|
yield commit
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
691
|
+
|
|
692
|
+
should_retry = true
|
|
693
|
+
# @type [Google::Cloud::Spanner::V1::MultiplexedSessionPrecommitToken]
|
|
694
|
+
precommit_token = nil
|
|
695
|
+
while should_retry
|
|
696
|
+
commit_resp = service.commit(path,
|
|
697
|
+
commit.mutations,
|
|
698
|
+
transaction_id: transaction_id,
|
|
699
|
+
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
700
|
+
isolation_level: isolation_level,
|
|
701
|
+
commit_options: commit_options,
|
|
702
|
+
request_options: request_options,
|
|
703
|
+
call_options: call_options,
|
|
704
|
+
precommit_token: precommit_token)
|
|
705
|
+
|
|
706
|
+
precommit_token = commit_resp.precommit_token
|
|
707
|
+
should_retry = !precommit_token.nil?
|
|
708
|
+
end
|
|
709
|
+
|
|
684
710
|
@last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
685
711
|
resp = CommitResponse.from_grpc commit_resp
|
|
686
712
|
commit_options ? resp : resp.timestamp
|
|
@@ -818,6 +844,8 @@ module Google
|
|
|
818
844
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
819
845
|
# mutations will not be recorded in change streams with DDL option
|
|
820
846
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
847
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
848
|
+
# isolation level for the transaction.
|
|
821
849
|
# @param [Hash] commit_options A hash of commit options.
|
|
822
850
|
# e.g., return_commit_stats. Commit options are optional.
|
|
823
851
|
# The following options can be provided:
|
|
@@ -890,10 +918,12 @@ module Google
|
|
|
890
918
|
#
|
|
891
919
|
def upsert table, *rows,
|
|
892
920
|
transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
893
|
-
|
|
921
|
+
isolation_level: nil, commit_options: nil, request_options: nil,
|
|
922
|
+
call_options: nil
|
|
894
923
|
opts = {
|
|
895
924
|
transaction_id: transaction_id,
|
|
896
925
|
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
926
|
+
isolation_level: isolation_level,
|
|
897
927
|
commit_options: commit_options,
|
|
898
928
|
request_options: request_options,
|
|
899
929
|
call_options: call_options
|
|
@@ -938,6 +968,8 @@ module Google
|
|
|
938
968
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
939
969
|
# mutations will not be recorded in change streams with DDL option
|
|
940
970
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
971
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
972
|
+
# isolation level for the transaction.
|
|
941
973
|
# @param [Hash] commit_options A hash of commit options.
|
|
942
974
|
# e.g., return_commit_stats. Commit options are optional.
|
|
943
975
|
# The following options can be provided:
|
|
@@ -1010,10 +1042,12 @@ module Google
|
|
|
1010
1042
|
#
|
|
1011
1043
|
def insert table, *rows,
|
|
1012
1044
|
transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
1013
|
-
|
|
1045
|
+
isolation_level: nil, commit_options: nil, request_options: nil,
|
|
1046
|
+
call_options: nil
|
|
1014
1047
|
opts = {
|
|
1015
1048
|
transaction_id: transaction_id,
|
|
1016
1049
|
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
1050
|
+
isolation_level: isolation_level,
|
|
1017
1051
|
commit_options: commit_options,
|
|
1018
1052
|
request_options: request_options,
|
|
1019
1053
|
call_options: call_options
|
|
@@ -1057,6 +1091,8 @@ module Google
|
|
|
1057
1091
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
1058
1092
|
# mutations will not be recorded in change streams with DDL option
|
|
1059
1093
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
1094
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
1095
|
+
# isolation level for the transaction.
|
|
1060
1096
|
# @param [Hash] commit_options A hash of commit options.
|
|
1061
1097
|
# e.g., return_commit_stats. Commit options are optional.
|
|
1062
1098
|
# The following options can be provided:
|
|
@@ -1129,10 +1165,12 @@ module Google
|
|
|
1129
1165
|
#
|
|
1130
1166
|
def update table, *rows,
|
|
1131
1167
|
transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
1132
|
-
|
|
1168
|
+
isolation_level: nil, commit_options: nil, request_options: nil,
|
|
1169
|
+
call_options: nil
|
|
1133
1170
|
opts = {
|
|
1134
1171
|
transaction_id: transaction_id,
|
|
1135
1172
|
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
1173
|
+
isolation_level: isolation_level,
|
|
1136
1174
|
commit_options: commit_options,
|
|
1137
1175
|
request_options: request_options,
|
|
1138
1176
|
call_options: call_options
|
|
@@ -1178,6 +1216,8 @@ module Google
|
|
|
1178
1216
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
1179
1217
|
# mutations will not be recorded in change streams with DDL option
|
|
1180
1218
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
1219
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
1220
|
+
# isolation level for the transaction.
|
|
1181
1221
|
# @param [Hash] commit_options A hash of commit options.
|
|
1182
1222
|
# e.g., return_commit_stats. Commit options are optional.
|
|
1183
1223
|
# The following options can be provided:
|
|
@@ -1251,10 +1291,11 @@ module Google
|
|
|
1251
1291
|
#
|
|
1252
1292
|
def replace table, *rows,
|
|
1253
1293
|
transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
1254
|
-
commit_options: nil, request_options: nil, call_options: nil
|
|
1294
|
+
isolation_level: nil, commit_options: nil, request_options: nil, call_options: nil
|
|
1255
1295
|
opts = {
|
|
1256
1296
|
transaction_id: transaction_id,
|
|
1257
1297
|
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
1298
|
+
isolation_level: isolation_level,
|
|
1258
1299
|
commit_options: commit_options,
|
|
1259
1300
|
request_options: request_options,
|
|
1260
1301
|
call_options: call_options
|
|
@@ -1279,6 +1320,8 @@ module Google
|
|
|
1279
1320
|
# @param [Boolean] exclude_txn_from_change_streams If set to true,
|
|
1280
1321
|
# mutations will not be recorded in change streams with DDL option
|
|
1281
1322
|
# `allow_txn_exclusion=true`. Used if starting a new transaction.
|
|
1323
|
+
# @param [Google::Cloud::Spanner::V1::TransactionOptions::IsolationLevel] isolation_level Optional. The
|
|
1324
|
+
# isolation level for the transaction.
|
|
1282
1325
|
# @param [Hash] commit_options A hash of commit options.
|
|
1283
1326
|
# e.g., return_commit_stats. Commit options are optional.
|
|
1284
1327
|
# The following options can be provided:
|
|
@@ -1348,10 +1391,12 @@ module Google
|
|
|
1348
1391
|
#
|
|
1349
1392
|
def delete table, keys = [],
|
|
1350
1393
|
transaction_id: nil, exclude_txn_from_change_streams: false,
|
|
1351
|
-
|
|
1394
|
+
isolation_level: nil, commit_options: nil, request_options: nil,
|
|
1395
|
+
call_options: nil
|
|
1352
1396
|
opts = {
|
|
1353
1397
|
transaction_id: transaction_id,
|
|
1354
1398
|
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
1399
|
+
isolation_level: isolation_level,
|
|
1355
1400
|
commit_options: commit_options,
|
|
1356
1401
|
request_options: request_options,
|
|
1357
1402
|
call_options: call_options
|
|
@@ -1369,9 +1414,15 @@ module Google
|
|
|
1369
1414
|
true
|
|
1370
1415
|
end
|
|
1371
1416
|
|
|
1372
|
-
|
|
1417
|
+
# Explicitly begins a new transaction and creates a server-side transaction object.
|
|
1418
|
+
# Unlike {#create_empty_transaction}, this method makes an immediate
|
|
1419
|
+
# `BeginTransaction` RPC call.
|
|
1420
|
+
#
|
|
1421
|
+
# @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
|
|
1422
|
+
# When `exclude_txn_from_change_streams` is set to `true`, it prevents read
|
|
1423
|
+
# or write transactions from being tracked in change streams.
|
|
1373
1424
|
# @private
|
|
1374
|
-
#
|
|
1425
|
+
# @return [::Google::Cloud::Spanner::Transaction]
|
|
1375
1426
|
def create_transaction exclude_txn_from_change_streams: false
|
|
1376
1427
|
route_to_leader = LARHeaders.begin_transaction true
|
|
1377
1428
|
tx_grpc = service.begin_transaction path,
|
|
@@ -1380,37 +1431,34 @@ module Google
|
|
|
1380
1431
|
Transaction.from_grpc tx_grpc, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams
|
|
1381
1432
|
end
|
|
1382
1433
|
|
|
1383
|
-
|
|
1434
|
+
# Creates a new empty transaction wrapper without a server-side object.
|
|
1435
|
+
# This is used for inline-begin transactions and does not make an RPC call.
|
|
1436
|
+
# See {#create_transaction} for the RPC-based method.
|
|
1437
|
+
#
|
|
1438
|
+
# @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
|
|
1439
|
+
# When `exclude_txn_from_change_streams` is set to `true`, it prevents read
|
|
1440
|
+
# or write transactions from being tracked in change streams.
|
|
1441
|
+
# @param previous_transaction_id [::String, nil] Optional.
|
|
1442
|
+
# An id of the previous transaction, if this new transaction wrapper is being created
|
|
1443
|
+
# as a part of a retry. Previous transaction id should be added to TransactionOptions
|
|
1444
|
+
# of a new ReadWrite transaction when retry is attempted.
|
|
1384
1445
|
# @private
|
|
1385
|
-
#
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
end
|
|
1390
|
-
|
|
1391
|
-
##
|
|
1392
|
-
# Reloads the session resource. Useful for determining if the session is
|
|
1393
|
-
# still valid on the Spanner API.
|
|
1394
|
-
def reload!
|
|
1395
|
-
ensure_service!
|
|
1396
|
-
@grpc = service.get_session path
|
|
1397
|
-
@last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
1398
|
-
self
|
|
1399
|
-
rescue Google::Cloud::NotFoundError
|
|
1400
|
-
labels = @grpc.labels.to_h unless @grpc.labels.to_h.empty?
|
|
1401
|
-
@grpc = service.create_session \
|
|
1402
|
-
V1::Spanner::Paths.database_path(
|
|
1403
|
-
project: project_id, instance: instance_id, database: database_id
|
|
1404
|
-
),
|
|
1405
|
-
labels: labels
|
|
1406
|
-
@last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
1407
|
-
self
|
|
1446
|
+
# @return [::Google::Cloud::Spanner::Transaction] The new *empty-wrapper* transaction object.
|
|
1447
|
+
def create_empty_transaction exclude_txn_from_change_streams: false, previous_transaction_id: nil
|
|
1448
|
+
Transaction.from_grpc nil, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams,
|
|
1449
|
+
previous_transaction_id: previous_transaction_id
|
|
1408
1450
|
end
|
|
1409
1451
|
|
|
1410
|
-
|
|
1452
|
+
# If the session is non-multiplexed, keeps the session alive by executing `"SELECT 1"`.
|
|
1453
|
+
# This method will re-create the session if necessary.
|
|
1454
|
+
# For multiplexed session the keepalive is not required and this method immediately returns `true`.
|
|
1411
1455
|
# @private
|
|
1412
|
-
#
|
|
1456
|
+
# @return [::Boolean]
|
|
1457
|
+
# `true` if the session is multiplexed or if the keepalive was successful for non-multiplexed session,
|
|
1458
|
+
# `false` if the non-multiplexed session was not found and the had to be recreated.
|
|
1413
1459
|
def keepalive!
|
|
1460
|
+
return true if multiplexed?
|
|
1461
|
+
|
|
1414
1462
|
ensure_service!
|
|
1415
1463
|
route_to_leader = LARHeaders.execute_query false
|
|
1416
1464
|
execute_query "SELECT 1", route_to_leader: route_to_leader
|
|
@@ -1425,15 +1473,19 @@ module Google
|
|
|
1425
1473
|
false
|
|
1426
1474
|
end
|
|
1427
1475
|
|
|
1428
|
-
|
|
1429
|
-
#
|
|
1476
|
+
# Permanently deletes the session unless this session is multiplexed.
|
|
1477
|
+
# Multiplexed sessions can not be deleted, and this method immediately returns.
|
|
1478
|
+
# @private
|
|
1479
|
+
# @return [void]
|
|
1430
1480
|
def release!
|
|
1481
|
+
return if multiplexed?
|
|
1431
1482
|
ensure_service!
|
|
1432
1483
|
service.delete_session path
|
|
1433
1484
|
end
|
|
1434
1485
|
|
|
1435
1486
|
# Determines if the session has been idle longer than the given
|
|
1436
|
-
# duration.
|
|
1487
|
+
# duration in seconds.
|
|
1488
|
+
#
|
|
1437
1489
|
# @param duration_sec [::Numeric] interval in seconds
|
|
1438
1490
|
# @private
|
|
1439
1491
|
# @return [::Boolean]
|
|
@@ -1442,7 +1494,17 @@ module Google
|
|
|
1442
1494
|
Process.clock_gettime(Process::CLOCK_MONOTONIC) > @last_updated_at + duration_sec
|
|
1443
1495
|
end
|
|
1444
1496
|
|
|
1445
|
-
#
|
|
1497
|
+
# Determines if the session did exist for at least the given
|
|
1498
|
+
# duration in seconds.
|
|
1499
|
+
#
|
|
1500
|
+
# @param duration_sec [::Numeric] interval in seconds
|
|
1501
|
+
# @private
|
|
1502
|
+
# @return [::Boolean]
|
|
1503
|
+
def existed_since? duration_sec
|
|
1504
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) > @created_time + duration_sec
|
|
1505
|
+
end
|
|
1506
|
+
|
|
1507
|
+
# Creates a new `Spanner::Session` instance from a `V1::Session` object.
|
|
1446
1508
|
# @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
|
|
1447
1509
|
# @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` ref.
|
|
1448
1510
|
# @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
|
|
@@ -1461,6 +1523,13 @@ module Google
|
|
|
1461
1523
|
|
|
1462
1524
|
protected
|
|
1463
1525
|
|
|
1526
|
+
# Whether this session is multiplexed.
|
|
1527
|
+
# @private
|
|
1528
|
+
# @return [::Boolean]
|
|
1529
|
+
def multiplexed?
|
|
1530
|
+
@grpc.multiplexed
|
|
1531
|
+
end
|
|
1532
|
+
|
|
1464
1533
|
##
|
|
1465
1534
|
# @private Raise an error unless an active connection to the service is
|
|
1466
1535
|
# available.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Copyright 2025 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
|
+
require "concurrent"
|
|
16
|
+
require "google/cloud/spanner/session"
|
|
17
|
+
require "google/cloud/spanner/session_creation_options"
|
|
18
|
+
|
|
19
|
+
module Google
|
|
20
|
+
module Cloud
|
|
21
|
+
module Spanner
|
|
22
|
+
# Cache for the multiplex `{Google::Cloud::Spanner::Session}` instance.
|
|
23
|
+
# @private
|
|
24
|
+
class SessionCache
|
|
25
|
+
# Time in seconds before this SessionCache will refresh the session.
|
|
26
|
+
# Counted from the session creation time (not from last usage).
|
|
27
|
+
# This is specific to multiplex sessions.
|
|
28
|
+
# The backend can keep sessions alive for quite a bit longer (28 days) but
|
|
29
|
+
# we perform refresh after 7 days.
|
|
30
|
+
# @private
|
|
31
|
+
SESSION_REFRESH_SEC = 7 * 24 * 3600
|
|
32
|
+
|
|
33
|
+
# Create a single-session "cache" for multiplex sessions.
|
|
34
|
+
# @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` reference.
|
|
35
|
+
# @param session_creation_options [::Google::Cloud::Spanner::SessionCreationOptions] Required.
|
|
36
|
+
# @private
|
|
37
|
+
def initialize service, session_creation_options
|
|
38
|
+
@service = service
|
|
39
|
+
@session_creation_options = session_creation_options
|
|
40
|
+
@mutex = Mutex.new
|
|
41
|
+
@session = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Yields the current session to run an operation (or a series of operations) on.
|
|
45
|
+
# @yield session A session to run requests on
|
|
46
|
+
# @yieldparam session [::Google::Cloud::Spanner::Session]
|
|
47
|
+
# @private
|
|
48
|
+
# @yieldreturn [::Object] The result of the operation that ran on a session.
|
|
49
|
+
# @return [::Object] The value returned by the yielded block.
|
|
50
|
+
def with_session
|
|
51
|
+
ensure_session!
|
|
52
|
+
yield @session
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Re-initializes the session in the session cache.
|
|
56
|
+
# @private
|
|
57
|
+
# @return [::Boolean]
|
|
58
|
+
def reset!
|
|
59
|
+
@mutex.synchronize do
|
|
60
|
+
@session = create_new_session
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Closes the pool. This is a NOP for Multiplex Session Cache since
|
|
67
|
+
# multiplex sessions don't require cleanup.
|
|
68
|
+
# @private
|
|
69
|
+
# @return [::Boolean]
|
|
70
|
+
def close
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Returns the current session. For use in the `{Spanner::BatchClient}`
|
|
75
|
+
# where usage pattern is incompatible with `with_session`.
|
|
76
|
+
# For other uses please use `with_session` instead.
|
|
77
|
+
# @private
|
|
78
|
+
# @return [::Google::Cloud::Spanner::Session]
|
|
79
|
+
def session
|
|
80
|
+
ensure_session!
|
|
81
|
+
@session
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Ensures that a single session exists and is current.
|
|
87
|
+
# @private
|
|
88
|
+
# @return [nil]
|
|
89
|
+
def ensure_session!
|
|
90
|
+
return unless @session.nil? || @session.existed_since?(SESSION_REFRESH_SEC)
|
|
91
|
+
|
|
92
|
+
@mutex.synchronize do
|
|
93
|
+
return unless @session.nil? || @session.existed_since?(SESSION_REFRESH_SEC)
|
|
94
|
+
@session = create_new_session
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Creates a new multiplexed `Spanner::Session`.
|
|
101
|
+
# @private
|
|
102
|
+
# @return [::Google::Cloud::Spanner::Session]
|
|
103
|
+
def create_new_session
|
|
104
|
+
ensure_service!
|
|
105
|
+
grpc = @service.create_session(
|
|
106
|
+
@session_creation_options.database_path,
|
|
107
|
+
labels: @session_creation_options.session_labels,
|
|
108
|
+
database_role: @session_creation_options.session_creator_role,
|
|
109
|
+
multiplexed: true
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
Session.from_grpc grpc, @service, query_options: @session_creation_options.query_options
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Raise an error unless an active connection to the service is available.
|
|
116
|
+
# @private
|
|
117
|
+
# @raise [::StandardError]
|
|
118
|
+
# @return [void]
|
|
119
|
+
def ensure_service!
|
|
120
|
+
raise "Must have active connection to service" unless @service
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Copyright 2025 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
|
+
module Google
|
|
16
|
+
module Cloud
|
|
17
|
+
module Spanner
|
|
18
|
+
# Options for creating new sessions that clients use
|
|
19
|
+
# to parametrize Pool and SessionCache.
|
|
20
|
+
# Example: session labels.
|
|
21
|
+
# @private
|
|
22
|
+
class SessionCreationOptions
|
|
23
|
+
# The full path to the Spanner database. Values are of the form:
|
|
24
|
+
# `projects/<project_id>/instances/<instance_id>/databases/<database_id>.
|
|
25
|
+
# @private
|
|
26
|
+
# @return [::String]
|
|
27
|
+
attr_reader :database_path
|
|
28
|
+
|
|
29
|
+
# The labels to be applied to all sessions created by the client.
|
|
30
|
+
# Optional. Example: `"team" => "billing-service"`.
|
|
31
|
+
# @private
|
|
32
|
+
# @return [::Hash, nil]
|
|
33
|
+
attr_reader :session_labels
|
|
34
|
+
|
|
35
|
+
# The Spanner session creator role.
|
|
36
|
+
# Optional. Example: `analyst`.
|
|
37
|
+
# @return [::String, nil]
|
|
38
|
+
attr_reader :session_creator_role
|
|
39
|
+
|
|
40
|
+
# A hash of values to specify the custom query options for executing SQL query.
|
|
41
|
+
# Optional. Example option: `:optimizer_version`.
|
|
42
|
+
# @private
|
|
43
|
+
# @return [::Hash, nil]
|
|
44
|
+
attr_reader :query_options
|
|
45
|
+
|
|
46
|
+
# Creates a new SessionCreationOptions object.
|
|
47
|
+
# @param database_path [::String]
|
|
48
|
+
# The full path to the Spanner database. Values are of the form:
|
|
49
|
+
# `projects/<project_id>/instances/<instance_id>/databases/<database_id>.
|
|
50
|
+
# @param session_labels [::Hash, nil] Optional. The labels to be applied to all sessions
|
|
51
|
+
# created by the client. Example: `"team" => "billing-service"`.
|
|
52
|
+
# @param session_creator_role [::String, nil] Optional. The Spanner session creator role.
|
|
53
|
+
# Example: `analyst`.
|
|
54
|
+
# @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
|
|
55
|
+
# query options for executing SQL query. Example option: `:optimizer_version`.
|
|
56
|
+
# @private
|
|
57
|
+
def initialize database_path:, session_labels: nil, session_creator_role: nil, query_options: nil
|
|
58
|
+
if database_path.nil? || database_path.empty?
|
|
59
|
+
raise ArgumentError, "database_path is required for session creation options"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@database_path = database_path
|
|
63
|
+
@session_labels = session_labels
|
|
64
|
+
@session_creator_role = session_creator_role
|
|
65
|
+
@query_options = query_options
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -41,9 +41,26 @@ module Google
|
|
|
41
41
|
# end
|
|
42
42
|
#
|
|
43
43
|
class Snapshot
|
|
44
|
-
#
|
|
44
|
+
# A `V1::Session` reference.
|
|
45
|
+
# @private
|
|
46
|
+
# @return [::Google::Cloud::Spanner::V1::Session]
|
|
45
47
|
attr_accessor :session
|
|
46
48
|
|
|
49
|
+
# Creates a new `Spanner::Snapshot` instance.
|
|
50
|
+
# @param grpc [::Google::Cloud::Spanner::V1::Transaction]
|
|
51
|
+
# Underlying `V1::Transaction` object.
|
|
52
|
+
# @param session [::Google::Cloud::Spanner::Session] A `Spanner::Session` reference.
|
|
53
|
+
# @param directed_read_options [::Hash, nil] Optional. Client options used to set
|
|
54
|
+
# the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
|
|
55
|
+
# Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
|
|
56
|
+
# @private
|
|
57
|
+
# @return [::Google::Cloud::Spanner::Snapshot]
|
|
58
|
+
def initialize grpc, session, directed_read_options: nil
|
|
59
|
+
@grpc = grpc
|
|
60
|
+
@session = session
|
|
61
|
+
@directed_read_options = directed_read_options
|
|
62
|
+
end
|
|
63
|
+
|
|
47
64
|
##
|
|
48
65
|
# Identifier of the transaction results were run in.
|
|
49
66
|
# @return [String] The transaction id.
|
|
@@ -536,15 +553,18 @@ module Google
|
|
|
536
553
|
exclude_end: exclude_end
|
|
537
554
|
end
|
|
538
555
|
|
|
539
|
-
|
|
540
|
-
# @private Creates a new Snapshot instance from a
|
|
556
|
+
# Creates a new `Spanner::Snapshot` instance from a
|
|
541
557
|
# `Google::Cloud::Spanner::V1::Transaction`.
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
558
|
+
# @param grpc [::Google::Cloud::Spanner::V1::Transaction]
|
|
559
|
+
# Underlying `V1::Transaction` object.
|
|
560
|
+
# @param session [::Google::Cloud::Spanner::Session] A `Spanner::Session` reference.
|
|
561
|
+
# @param directed_read_options [::Hash, nil] Optional. Client options used to set
|
|
562
|
+
# the `directed_read_options` for all ReadRequests and ExecuteSqlRequests.
|
|
563
|
+
# Converts to `V1::DirectedReadOptions`. Example option: `:exclude_replicas`.
|
|
564
|
+
# @private
|
|
565
|
+
# @return [::Google::Cloud::Spanner::Snapshot]
|
|
566
|
+
def self.from_grpc grpc, session, directed_read_options: nil
|
|
567
|
+
new grpc, session, directed_read_options: directed_read_options
|
|
548
568
|
end
|
|
549
569
|
|
|
550
570
|
protected
|