Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 53cf34d

Browse files
committed
feat: Reworked the wait_for_consistency call
1 parent 3d714e2 commit 53cf34d

7 files changed

Lines changed: 290 additions & 268 deletions

File tree

google/cloud/bigtable/admin_v2/overlay/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
from .types import (
3333
RestoreTableOperation,
34-
CheckConsistencyPollingFuture,
3534
)
3635

3736
from .services.bigtable_table_admin import (
@@ -40,6 +39,5 @@
4039

4140
__all__ = (
4241
"RestoreTableOperation",
43-
"CheckConsistencyPollingFuture",
4442
"BigtableTableAdminClient",
4543
)

google/cloud/bigtable/admin_v2/overlay/services/bigtable_table_admin/client.py

Lines changed: 68 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
from google.cloud.bigtable.admin_v2.services.bigtable_table_admin.transports.base import (
5151
BigtableTableAdminTransport,
5252
)
53-
from google.cloud.bigtable.admin_v2.overlay.types import consistency, restore_table
53+
from google.cloud.bigtable.admin_v2.overlay.types import (
54+
consistency,
55+
restore_table,
56+
wait_for_consistency_request,
57+
)
5458

5559
from google.cloud.bigtable.gapic_version import __version__ as bigtable_version
5660

@@ -224,23 +228,22 @@ def sample_restore_table():
224228
)
225229
return restore_table_operation
226230

231+
227232
def wait_for_consistency(
228233
self,
229234
request: Optional[
230-
Union[bigtable_table_admin.CheckConsistencyRequest, dict]
235+
Union[wait_for_consistency_request.WaitForConsistencyRequest, dict]
231236
] = None,
232237
*,
233238
name: Optional[str] = None,
234-
consistency_token: Optional[str] = None,
235239
retry: OptionalRetry = gapic_v1.method.DEFAULT,
236240
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
237241
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
238-
) -> consistency.CheckConsistencyPollingFuture:
239-
r"""Creates a polling future that periodically checks replication
240-
consistency based on a consistency token, that is, if replication
241-
has caught up based on the conditions specified in the token and
242-
the check request. The future will stop checking once the underlying
243-
:meth:`check_consistency` request involving that token returns True.
242+
) -> bool:
243+
r"""Blocks until the mutations for the specified Table that have been
244+
made before the call have been replicated. This is done by generating
245+
a consistency token for the Table, then polling :meth:`check_consistency`
246+
for the specified table until the call returns True.
244247
245248
.. code-block:: python
246249
@@ -257,41 +260,29 @@ def sample_wait_for_consistency():
257260
client = admin_v2.BigtableTableAdminClient()
258261
259262
# Initialize request argument(s)
260-
request = admin_v2.CheckConsistencyRequest(
263+
request = admin_v2.WaitForConsistencyRequest(
261264
name="name_value",
262-
consistency_token="consistency_token_value",
263265
)
264266
265267
# Make the request
266-
future = client.wait_for_consistency(request=request)
267-
268-
# Wait for the table to become consistent
269268
print("Waiting for operation to complete...")
270269
271-
response = future.result()
270+
response = client.wait_for_replication(request=request)
272271
273272
# Handle the response
274273
print(response)
275274
276275
Args:
277-
request (Union[google.cloud.bigtable.admin_v2.types.CheckConsistencyRequest, dict]):
278-
The request object. Request message for
279-
[google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
276+
request (Union[google.cloud.bigtable.admin_v2.overlay.types.WaitForConsistencyRequest, dict]):
277+
The request object.
280278
name (str):
281279
Required. The unique name of the Table for which to
282-
check replication consistency. Values are of the form
280+
create a consistency token. Values are of the form
283281
``projects/{project}/instances/{instance}/tables/{table}``.
284282
285283
This corresponds to the ``name`` field
286284
on the ``request`` instance; if ``request`` is provided, this
287285
should not be set.
288-
consistency_token (str):
289-
Required. The token created using
290-
GenerateConsistencyToken for the Table.
291-
292-
This corresponds to the ``consistency_token`` field
293-
on the ``request`` instance; if ``request`` is provided, this
294-
should not be set.
295286
retry (google.api_core.retry.Retry): Designation of what errors, if any,
296287
should be retried.
297288
timeout (float): The timeout for this request.
@@ -301,120 +292,67 @@ def sample_wait_for_consistency():
301292
be of type `bytes`.
302293
303294
Returns:
304-
google.cloud.bigtable.admin_v2.overlay.types.CheckConsistencyPollingFuture:
305-
An object representing a polling future.
306-
307-
The result type for the operation will be `bool`, and will return True when the
308-
consistency check involving the given consistency token returns True.
295+
bool:
296+
Returns `True` after the mutations of the specified table have been fully replicated
309297
"""
310-
api_call = functools.partial(
311-
self.check_consistency,
312-
request,
313-
name=name,
314-
consistency_token=consistency_token,
315-
timeout=timeout,
316-
metadata=metadata,
298+
# Create or coerce a protobuf request object.
299+
# - Quick check: If we got a request object, we should *not* have
300+
# gotten any keyword arguments that map to the request.
301+
flattened_params = [name]
302+
has_flattened_params = (
303+
len([param for param in flattened_params if param is not None]) > 0
304+
)
305+
if request is not None and has_flattened_params:
306+
raise ValueError(
307+
"If the `request` argument is set, then none of "
308+
"the individual field arguments should be set."
309+
)
310+
311+
# - Use the request object if provided (there's no risk of modifying the input as
312+
# there are no flattened fields), or create one.
313+
if not isinstance(
314+
request, wait_for_consistency_request.WaitForConsistencyRequest
315+
):
316+
request = wait_for_consistency_request.WaitForConsistencyRequest(request)
317+
# If we have keyword arguments corresponding to fields on the
318+
# request, apply these.
319+
if name is not None:
320+
request.name = name
321+
322+
323+
# Generate the consistency token.
324+
generate_consistency_token_request = bigtable_table_admin.GenerateConsistencyTokenRequest(
325+
name=request.name,
317326
)
318-
return consistency.CheckConsistencyPollingFuture(api_call, default_retry=retry)
319-
320-
def wait_for_replication(
321-
self,
322-
request: Optional[
323-
Union[bigtable_table_admin.GenerateConsistencyTokenRequest, dict]
324-
] = None,
325-
*,
326-
name: Optional[str] = None,
327-
retry: OptionalRetry = gapic_v1.method.DEFAULT,
328-
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
329-
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
330-
) -> consistency.CheckConsistencyPollingFuture:
331-
r"""Generates a consistency token for a Table, which will then
332-
be used to create a polling future for checking the replication
333-
consistency based on that token. The future will stop checking
334-
once the underlying :meth:`check_consistency` request involving
335-
that token returns True.
336-
337-
.. code-block:: python
338-
339-
# This snippet should be regarded as a code template only.
340-
# It will require modifications to work:
341-
# - It may require correct/in-range values for request initialization.
342-
# - It may require specifying regional endpoints when creating the service
343-
# client as shown in:
344-
# https://googleapis.dev/python/google-api-core/latest/client_options.html
345-
from google.cloud.bigtable import admin_v2
346-
347-
def sample_wait_for_replication():
348-
# Create a client
349-
client = admin_v2.BigtableTableAdminClient()
350-
351-
# Initialize request argument(s)
352-
request = admin_v2.GenerateConsistencyTokenRequest(
353-
name="name_value",
354-
)
355-
356-
# Make the request
357-
future = client.wait_for_replication(request=request)
358-
359-
# Wait for the table to become consistent
360-
print("Waiting for operation to complete...")
361-
362-
response = future.result()
363-
364-
# Handle the response
365-
print(response)
366-
367-
Args:
368-
request (Union[google.cloud.bigtable.admin_v2.types.GenerateConsistencyTokenRequest, dict]):
369-
The request object. Request message for
370-
[google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
371-
name (str):
372-
Required. The unique name of the Table for which to
373-
create a consistency token. Values are of the form
374-
``projects/{project}/instances/{instance}/tables/{table}``.
375-
376-
This corresponds to the ``name`` field
377-
on the ``request`` instance; if ``request`` is provided, this
378-
should not be set.
379-
retry (google.api_core.retry.Retry): Designation of what errors, if any,
380-
should be retried.
381-
timeout (float): The timeout for this request.
382-
metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
383-
sent along with the request as metadata. Normally, each value must be of type `str`,
384-
but for metadata keys ending with the suffix `-bin`, the corresponding values must
385-
be of type `bytes`.
386-
387-
Returns:
388-
google.cloud.bigtable.admin_v2.overlay.types.CheckConsistencyPollingFuture:
389-
An object representing a polling future.
390327

391-
The result type for the operation will be `bool`, and will return True when the
392-
consistency check involving the given consistency token returns True.
393-
"""
394328
generate_consistency_response = self.generate_consistency_token(
395-
request,
396-
name=name,
329+
generate_consistency_token_request,
397330
retry=retry,
398331
timeout=timeout,
399332
metadata=metadata,
400333
)
401334

402335
# Create the CheckConsistencyRequest object.
403-
check_consistency_request = bigtable_table_admin.CheckConsistencyRequest()
404-
405-
# If the generate_consistency_token request is valid, there's a name in the request object
406-
# or the name parameter.
407-
if isinstance(request, dict):
408-
check_consistency_request.name = request["name"]
409-
elif isinstance(request, bigtable_table_admin.GenerateConsistencyTokenRequest):
410-
check_consistency_request.name = request.name
411-
else:
412-
check_consistency_request.name = name
413-
414-
check_consistency_request.consistency_token = (
415-
generate_consistency_response.consistency_token
336+
check_consistency_request = bigtable_table_admin.CheckConsistencyRequest(
337+
name=request.name,
338+
consistency_token=generate_consistency_response.consistency_token
416339
)
417340

418-
return self.wait_for_consistency(
419-
check_consistency_request, retry=retry, timeout=timeout, metadata=metadata
341+
# Since the default values of StandardReadRemoteWrites and DataBoostReadLocalWrites evaluate to
342+
# False in proto plus, we cannot do a simple "if request.standard_read_remote_writes" to check
343+
# whether or not that field is defined in the original request object.
344+
mode_oneof_field = request._pb.WhichOneof("mode")
345+
if mode_oneof_field:
346+
setattr(check_consistency_request, mode_oneof_field, getattr(request, mode_oneof_field))
347+
348+
check_consistency_call = functools.partial(
349+
self.check_consistency,
350+
check_consistency_request,
351+
retry=retry,
352+
timeout=timeout,
353+
metadata=metadata
420354
)
355+
356+
# Block and wait until the polling harness returns True.
357+
check_consistency_future = consistency._CheckConsistencyPollingFuture(check_consistency_call)
358+
return check_consistency_future.result()

google/cloud/bigtable/admin_v2/overlay/types/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from .consistency import (
16-
CheckConsistencyPollingFuture,
17-
)
18-
1915
from .restore_table import (
2016
RestoreTableOperation,
2117
)
2218

19+
from .wait_for_consistency_request import (
20+
WaitForConsistencyRequest,
21+
)
22+
2323
__all__ = (
24-
"CheckConsistencyPollingFuture",
2524
"RestoreTableOperation",
25+
"WaitForConsistencyRequest",
2626
)

google/cloud/bigtable/admin_v2/overlay/types/consistency.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
OptionalRetry = Union[retries.Retry, object, None] # type: ignore
2626

2727

28-
class CheckConsistencyPollingFuture(polling.PollingFuture):
28+
class _CheckConsistencyPollingFuture(polling.PollingFuture):
2929
"""A Future that polls an underlying `check_consistency` operation until it returns True.
3030
3131
**This class should not be instantiated by users** and should only be instantiated by the admin
@@ -41,13 +41,8 @@ class CheckConsistencyPollingFuture(polling.PollingFuture):
4141
google.cloud.bigtable.admin_v2.types.CheckConsistencyResponse]):
4242
A :meth:`check_consistency
4343
<google.cloud.bigtable.admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.check_consistency>`
44-
call from the admin client. The call should fix every user parameter except for retry,
44+
call from the admin client. The call should fix every user parameter,
4545
which will be done via :meth:`functools.partial`.
46-
default_retry(Optional[google.api_core.retry.Retry]): The `retry` parameter passed in to either
47-
:meth:`wait_for_consistency
48-
<google.cloud.bigtable.admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_consistency>`
49-
or :meth:`wait_for_replication
50-
<google.cloud.bigtable.admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_replication>`
5146
polling (google.api_core.retry.Retry): The configuration used for polling.
5247
This parameter controls how often :meth:`done` is polled. If the
5348
``timeout`` argument is specified in the :meth:`result
@@ -60,17 +55,15 @@ def __init__(
6055
check_consistency_call: Callable[
6156
[OptionalRetry], bigtable_table_admin.CheckConsistencyResponse
6257
],
63-
default_retry: OptionalRetry = gapic_v1.method.DEFAULT,
6458
polling: retries.Retry = polling.DEFAULT_POLLING,
6559
**kwargs
6660
):
67-
super(CheckConsistencyPollingFuture, self).__init__(polling=polling, **kwargs)
61+
super(_CheckConsistencyPollingFuture, self).__init__(polling=polling, **kwargs)
6862

6963
# Done is called with two different scenarios, retry is specified or not specified.
7064
# API_call will be a functools partial with everything except retry specified because of
7165
# that.
7266
self._check_consistency_call = check_consistency_call
73-
self._default_retry = default_retry
7467

7568
def done(self, retry: OptionalRetry = None):
7669
"""Polls the underlying `check_consistency` call to see if the future is complete.
@@ -92,10 +85,8 @@ def done(self, retry: OptionalRetry = None):
9285
if self._result_set:
9386
return True
9487

95-
retry = retry or self._default_retry
96-
9788
try:
98-
check_consistency_response = self._check_consistency_call(retry=retry)
89+
check_consistency_response = self._check_consistency_call()
9990
if check_consistency_response.consistent:
10091
self.set_result(True)
10192

0 commit comments

Comments
 (0)