From f16bb4302739db18d919b9c69c6798812e348b4d Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Mon, 12 Oct 2026 19:52:52 +0000 Subject: [PATCH 1/3] docs(spanner): document queues in OVERVIEW.md and Client --- google-cloud-spanner/OVERVIEW.md | 54 +++++++++++++++++++ .../lib/google/cloud/spanner/client.rb | 20 +++++++ 2 files changed, 74 insertions(+) diff --git a/google-cloud-spanner/OVERVIEW.md b/google-cloud-spanner/OVERVIEW.md index 25c6195e..5b79d017 100644 --- a/google-cloud-spanner/OVERVIEW.md +++ b/google-cloud-spanner/OVERVIEW.md @@ -298,6 +298,60 @@ db.snapshot do |snp| end ``` +## Using queues + +A queue holds messages for consumers to receive. You create queues with the +`CREATE QUEUE` statement (see the [DDL +reference](https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language)). + +Use {Google::Cloud::Spanner::Commit#send_message Commit#send_message} to send a +message. The payload is converted the same way as column values, so wrap binary +data in a `StringIO`, as you would for a `BYTES` column: + +```ruby +require "google/cloud/spanner" + +spanner = Google::Cloud::Spanner.new + +db = spanner.client "my-instance", "my-database" + +db.commit do |c| + c.send_message "OrderQueue", 101, StringIO.new("Order payload") +end +``` + +Receive messages with the `RECEIVE_` table-valued function, and use +{Google::Cloud::Spanner::Transaction#ack_message Transaction#ack_message} to +acknowledge each one in the same transaction as the write it caused: + +```ruby +require "google/cloud/spanner" + +spanner = Google::Cloud::Spanner.new + +db = spanner.client "my-instance", "my-database" + +results = db.execute_query "SELECT Id, Payload FROM RECEIVE_OrderQueue()" + +results.rows.each do |row| + db.transaction do |tx| + tx.update "orders", [{ id: row[:Id], status: "PROCESSED" }] + tx.ack_message "OrderQueue", row[:Id] + end +end +``` + +Optional settings go in a {Google::Cloud::Spanner::SendOptions SendOptions} or +{Google::Cloud::Spanner::AckOptions AckOptions}, or in a hash with the same +keys: + +```ruby +db.commit do |c| + c.send_message "OrderQueue", 102, StringIO.new("Order payload"), + send_options: { deliver_time: Time.now + 300 } +end +``` + ## Deleting databases Use {Google::Cloud::Spanner::Admin::Database#database_admin diff --git a/google-cloud-spanner/lib/google/cloud/spanner/client.rb b/google-cloud-spanner/lib/google/cloud/spanner/client.rb index dacb4536..33d7d717 100644 --- a/google-cloud-spanner/lib/google/cloud/spanner/client.rb +++ b/google-cloud-spanner/lib/google/cloud/spanner/client.rb @@ -35,6 +35,12 @@ module Spanner # # A client is used to read and/or modify data in a Cloud Spanner database. # + # A client also works with queues. Send and acknowledge messages with + # {Commit#send_message} and {Commit#ack_message} inside {#commit}, or with + # {Transaction#send_message} and {Transaction#ack_message} inside + # {#transaction}. Receive messages by querying the queue's `RECEIVE_` + # function with {#execute_query}. + # # See {Google::Cloud::Spanner::Project#client}. # # @example @@ -506,6 +512,20 @@ def directed_read_options # puts "User #{row[:id]} is #{row[:name]}" # end # + # @example Receive messages from a queue with the RECEIVE_ function: + # require "google/cloud/spanner" + # + # spanner = Google::Cloud::Spanner.new + # + # db = spanner.client "my-instance", "my-database" + # + # # RECEIVE_ needs a strong read, which is the default here. + # results = db.execute_query "SELECT Id, Payload FROM RECEIVE_OrderQueue()" + # + # results.rows.each do |row| + # puts "Received message #{row[:Id]}" + # end + # def execute_query sql, params: nil, types: nil, single_use: nil, query_options: nil, request_options: nil, call_options: nil, directed_read_options: nil From a280313a17cae9189edfb8e2faa79ca1b2248c3f Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Tue, 20 Oct 2026 18:05:26 +0000 Subject: [PATCH 2/3] docs(spanner): document the deliver_time and ignore_not_found keywords Replace the OVERVIEW.md paragraph about SendOptions and AckOptions with the deliver_time: and ignore_not_found: keyword arguments. --- google-cloud-spanner/OVERVIEW.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/google-cloud-spanner/OVERVIEW.md b/google-cloud-spanner/OVERVIEW.md index 5b79d017..03ae303e 100644 --- a/google-cloud-spanner/OVERVIEW.md +++ b/google-cloud-spanner/OVERVIEW.md @@ -341,14 +341,14 @@ results.rows.each do |row| end ``` -Optional settings go in a {Google::Cloud::Spanner::SendOptions SendOptions} or -{Google::Cloud::Spanner::AckOptions AckOptions}, or in a hash with the same -keys: +To delay delivery, pass `deliver_time:`. To ack a message that might not +exist, pass `ignore_not_found: true`: ```ruby db.commit do |c| c.send_message "OrderQueue", 102, StringIO.new("Order payload"), - send_options: { deliver_time: Time.now + 300 } + deliver_time: Time.now + 300 + c.ack_message "OrderQueue", 101, ignore_not_found: true end ``` From 43e86f910e537e5fa74ff6643cb02221ee50157d Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Tue, 20 Oct 2026 23:03:28 +0000 Subject: [PATCH 3/3] docs(spanner): show the queue DDL and String payloads in OVERVIEW Show the CREATE QUEUE statement the examples assume, with a STRING(MAX) payload column, and pass a String instead of wrapping text in a StringIO. Add a short BYTES example that wraps binary data in a StringIO, as for BYTES columns in tables. --- google-cloud-spanner/OVERVIEW.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/google-cloud-spanner/OVERVIEW.md b/google-cloud-spanner/OVERVIEW.md index 03ae303e..c1acd557 100644 --- a/google-cloud-spanner/OVERVIEW.md +++ b/google-cloud-spanner/OVERVIEW.md @@ -303,10 +303,18 @@ end A queue holds messages for consumers to receive. You create queues with the `CREATE QUEUE` statement (see the [DDL reference](https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language)). +The examples in this section use this queue: + +```sql +CREATE QUEUE OrderQueue ( + Id INT64 NOT NULL, + Payload STRING(MAX) NOT NULL +) PRIMARY KEY (Id) +``` Use {Google::Cloud::Spanner::Commit#send_message Commit#send_message} to send a -message. The payload is converted the same way as column values, so wrap binary -data in a `StringIO`, as you would for a `BYTES` column: +message. The payload is converted the same way as column values, so pass a +`String` for a `STRING` payload column: ```ruby require "google/cloud/spanner" @@ -316,7 +324,16 @@ spanner = Google::Cloud::Spanner.new db = spanner.client "my-instance", "my-database" db.commit do |c| - c.send_message "OrderQueue", 101, StringIO.new("Order payload") + c.send_message "OrderQueue", 101, "Order payload" +end +``` + +If a queue's payload column is `BYTES`, wrap the binary data in a `StringIO`, +as you would for a `BYTES` column in a table: + +```ruby +db.commit do |c| + c.send_message "LabelQueue", 101, StringIO.new(File.binread("label.png")) end ``` @@ -346,7 +363,7 @@ exist, pass `ignore_not_found: true`: ```ruby db.commit do |c| - c.send_message "OrderQueue", 102, StringIO.new("Order payload"), + c.send_message "OrderQueue", 102, "Order payload", deliver_time: Time.now + 300 c.ack_message "OrderQueue", 101, ignore_not_found: true end