Skip to content

Commit 182ff9f

Browse files
authored
feat: add send and ack mutations Cloud Spanner Queues (#17728)
include unit and system tests Fixes #17727
1 parent 2d8093e commit 182ff9f

10 files changed

Lines changed: 764 additions & 5 deletions

File tree

‎packages/google-cloud-spanner/google/cloud/spanner_v1/_async/batch.py‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
from typing import List, Optional
2121

2222
from google.api_core.exceptions import InternalServerError
23+
from google.cloud._helpers import _datetime_to_pb_timestamp
2324

2425
from google.cloud.aio._cross_sync import CrossSync
2526
from google.cloud.spanner_v1._async._helpers import _retry, _retry_on_aborted_exception
2627
from google.cloud.spanner_v1._helpers import (
2728
AtomicCounter,
2829
_check_rst_stream_error,
30+
_make_list_value_pb,
2931
_make_list_value_pbs,
32+
_make_value_pb,
3033
_merge_client_context,
3134
_merge_request_options,
3235
_merge_Transaction_Options,
@@ -165,6 +168,49 @@ def delete(self, table, keyset):
165168
# TODO: Decide if we should add a span event per mutation:
166169
# https://github.com/googleapis/python-spanner/issues/1269
167170

171+
def send(self, queue, key, payload=None, deliver_time=None):
172+
"""Send a message to a Cloud Spanner queue.
173+
174+
:type queue: str
175+
:param queue: Name of the queue to which the message will be sent.
176+
177+
:type key: list
178+
:param key: The primary key of the message to be sent.
179+
180+
:type payload: object
181+
:param payload: (Optional) The payload of the message.
182+
183+
:type deliver_time: :class:`datetime.datetime`
184+
:param deliver_time: (Optional) The time at which Spanner will begin attempting to deliver the message.
185+
"""
186+
send_kwargs = {"queue": queue, "key": _make_list_value_pb(key)}
187+
if payload is not None:
188+
send_kwargs["payload"] = _make_value_pb(payload)
189+
if deliver_time is not None:
190+
send_kwargs["deliver_time"] = _datetime_to_pb_timestamp(deliver_time)
191+
192+
send = Mutation.Send(**send_kwargs)
193+
self._mutations.append(Mutation(send=send))
194+
195+
def ack(self, queue, key, ignore_not_found=None):
196+
"""Acknowledge a message in a Cloud Spanner queue.
197+
198+
:type queue: str
199+
:param queue: Name of the queue where the message to be acked is stored.
200+
201+
:type key: list
202+
:param key: The primary key of the message to be acked.
203+
204+
:type ignore_not_found: bool
205+
:param ignore_not_found: (Optional) Whether to ignore if the message does not exist.
206+
"""
207+
ack_kwargs = {"queue": queue, "key": _make_list_value_pb(key)}
208+
if ignore_not_found is not None:
209+
ack_kwargs["ignore_not_found"] = ignore_not_found
210+
211+
ack = Mutation.Ack(**ack_kwargs)
212+
self._mutations.append(Mutation(ack=ack))
213+
168214

169215
class Batch(_BatchBase):
170216
"""Accumulate mutations for transmission during :meth:`commit`."""

‎packages/google-cloud-spanner/google/cloud/spanner_v1/batch.py‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
from typing import List, Optional
2323

2424
from google.api_core.exceptions import InternalServerError
25+
from google.cloud._helpers import _datetime_to_pb_timestamp
2526

2627
from google.cloud.spanner_v1._helpers import (
2728
AtomicCounter,
2829
_check_rst_stream_error,
30+
_make_list_value_pb,
2931
_make_list_value_pbs,
32+
_make_value_pb,
3033
_merge_client_context,
3134
_merge_request_options,
3235
_merge_Transaction_Options,
@@ -142,6 +145,49 @@ def delete(self, table, keyset):
142145
delete = Mutation.Delete(table=table, key_set=keyset._to_pb())
143146
self._mutations.append(Mutation(delete=delete))
144147

148+
def send(self, queue, key, payload=None, deliver_time=None):
149+
"""Send a message to a Cloud Spanner queue.
150+
151+
:type queue: str
152+
:param queue: Name of the queue to which the message will be sent.
153+
154+
:type key: list
155+
:param key: The primary key of the message to be sent.
156+
157+
:type payload: object
158+
:param payload: (Optional) The payload of the message.
159+
160+
:type deliver_time: :class:`datetime.datetime`
161+
:param deliver_time: (Optional) The time at which Spanner will begin attempting to deliver the message.
162+
"""
163+
send_kwargs = {"queue": queue, "key": _make_list_value_pb(key)}
164+
if payload is not None:
165+
send_kwargs["payload"] = _make_value_pb(payload)
166+
if deliver_time is not None:
167+
send_kwargs["deliver_time"] = _datetime_to_pb_timestamp(deliver_time)
168+
169+
send = Mutation.Send(**send_kwargs)
170+
self._mutations.append(Mutation(send=send))
171+
172+
def ack(self, queue, key, ignore_not_found=None):
173+
"""Acknowledge a message in a Cloud Spanner queue.
174+
175+
:type queue: str
176+
:param queue: Name of the queue where the message to be acked is stored.
177+
178+
:type key: list
179+
:param key: The primary key of the message to be acked.
180+
181+
:type ignore_not_found: bool
182+
:param ignore_not_found: (Optional) Whether to ignore if the message does not exist.
183+
"""
184+
ack_kwargs = {"queue": queue, "key": _make_list_value_pb(key)}
185+
if ignore_not_found is not None:
186+
ack_kwargs["ignore_not_found"] = ignore_not_found
187+
188+
ack = Mutation.Ack(**ack_kwargs)
189+
self._mutations.append(Mutation(ack=ack))
190+
145191

146192
class Batch(_BatchBase):
147193
"""Accumulate mutations for transmission during :meth:`commit`."""

0 commit comments

Comments
 (0)