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

Commit 36c2471

Browse files
committed
Reworked async_consistency and added async client to __init__.py
1 parent 99325ab commit 36c2471

6 files changed

Lines changed: 252 additions & 130 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@
3434
)
3535

3636
from .services.bigtable_table_admin import (
37+
BigtableTableAdminAsyncClient,
3738
BigtableTableAdminClient,
3839
)
3940

4041
__all__ = (
4142
"RestoreTableOperation",
43+
"BigtableTableAdminAsyncClient",
4244
"BigtableTableAdminClient",
4345
)

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
# TODO: Add the async client after owlbot changes.
1616

17+
from .async_client import BigtableTableAdminAsyncClient
1718
from .client import BigtableTableAdminClient
1819

19-
__all__ = ("BigtableTableAdminClient",)
20+
__all__ = (
21+
"BigtableTableAdminAsyncClient",
22+
"BigtableTableAdminClient",
23+
)

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

Lines changed: 86 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
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 async_consistency
53+
from google.cloud.bigtable.admin_v2.overlay.types import async_consistency, wait_for_consistency_request
5454

5555
from google.cloud.bigtable.gapic_version import __version__ as bigtable_version
5656

@@ -133,20 +133,19 @@ def __init__(
133133
async def wait_for_consistency(
134134
self,
135135
request: Optional[
136-
Union[bigtable_table_admin.CheckConsistencyRequest, dict]
136+
Union[wait_for_consistency_request.WaitForConsistencyRequest, dict]
137137
] = None,
138138
*,
139139
name: Optional[str] = None,
140-
consistency_token: Optional[str] = None,
141140
retry: OptionalRetry = gapic_v1.method.DEFAULT,
142141
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
143142
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
144-
) -> async_consistency.AsyncCheckConsistencyPollingFuture:
145-
r"""Creates a polling future that periodically checks replication
146-
consistency based on a consistency token, that is, if replication
147-
has caught up based on the conditions specified in the token and
148-
the check request. The future will stop checking once the underlying
149-
:meth:`check_consistency` request involving that token returns True.
143+
) -> bool:
144+
r"""Blocks until the mutations for the specified Table that have been
145+
made before the call have been replicated or reads using an app profile with `DataBoostIsolationReadOnly`
146+
can see all writes committed before the token was created. This is done by generating
147+
a consistency token for the Table, then polling :meth:`check_consistency`
148+
for the specified table until the call returns True.
150149
151150
.. code-block:: python
152151
@@ -160,44 +159,32 @@ async def wait_for_consistency(
160159
161160
def sample_wait_for_consistency():
162161
# Create a client
163-
client = admin_v2.BigtableTableAdminClient()
162+
client = admin_v2.BigtableTableAdminAsyncClient()
164163
165164
# Initialize request argument(s)
166-
request = admin_v2.CheckConsistencyRequest(
165+
request = admin_v2.WaitForConsistencyRequest(
167166
name="name_value",
168-
consistency_token="consistency_token_value",
169167
)
170168
171169
# Make the request
172-
future = client.wait_for_consistency(request=request)
173-
174-
# Wait for the table to become consistent
175170
print("Waiting for operation to complete...")
176171
177-
response = future.result()
172+
response = await client.wait_for_replication(request=request)
178173
179174
# Handle the response
180175
print(response)
181176
182177
Args:
183-
request (Union[google.cloud.bigtable.admin_v2.types.CheckConsistencyRequest, dict]):
184-
The request object. Request message for
185-
[google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
178+
request (Union[google.cloud.bigtable.admin_v2.overlay.types.WaitForConsistencyRequest, dict]):
179+
The request object.
186180
name (str):
187181
Required. The unique name of the Table for which to
188-
check replication consistency. Values are of the form
182+
create a consistency token. Values are of the form
189183
``projects/{project}/instances/{instance}/tables/{table}``.
190184
191185
This corresponds to the ``name`` field
192186
on the ``request`` instance; if ``request`` is provided, this
193187
should not be set.
194-
consistency_token (str):
195-
Required. The token created using
196-
GenerateConsistencyToken for the Table.
197-
198-
This corresponds to the ``consistency_token`` field
199-
on the ``request`` instance; if ``request`` is provided, this
200-
should not be set.
201188
retry (google.api_core.retry.Retry): Designation of what errors, if any,
202189
should be retried.
203190
timeout (float): The timeout for this request.
@@ -207,22 +194,83 @@ def sample_wait_for_consistency():
207194
be of type `bytes`.
208195
209196
Returns:
210-
google.cloud.bigtable.admin_v2.overlay.types.async_consistency.AsyncCheckConsistencyPollingFuture:
211-
An object representing a polling future.
197+
bool:
198+
If the `standard_read_remote_writes` mode is specified in the request object, returns
199+
`True` after the mutations of the specified table have been fully replicated. If the
200+
`data_boost_read_local_writes` mode is specified in the request object, returns `True`
201+
after reads using an app profile with `DataBoostIsolationReadOnly` can see all writes
202+
committed before the token was created.
212203
213-
The result type for the operation will be `bool`, and will return True when the
214-
consistency check involving the given consistency token returns True.
204+
Raises:
205+
google.api_core.GoogleAPICallError: If the operation errors or if
206+
the timeout is reached before the operation completes.
215207
"""
216-
api_call = functools.partial(
208+
# Create or coerce a protobuf request object.
209+
# - Quick check: If we got a request object, we should *not* have
210+
# gotten any keyword arguments that map to the request.
211+
flattened_params = [name]
212+
has_flattened_params = (
213+
len([param for param in flattened_params if param is not None]) > 0
214+
)
215+
if request is not None and has_flattened_params:
216+
raise ValueError(
217+
"If the `request` argument is set, then none of "
218+
"the individual field arguments should be set."
219+
)
220+
221+
# - Use the request object if provided (there's no risk of modifying the input as
222+
# there are no flattened fields), or create one.
223+
if not isinstance(
224+
request, wait_for_consistency_request.WaitForConsistencyRequest
225+
):
226+
request = wait_for_consistency_request.WaitForConsistencyRequest(request)
227+
# If we have keyword arguments corresponding to fields on the
228+
# request, apply these.
229+
if name is not None:
230+
request.name = name
231+
232+
# Generate the consistency token.
233+
generate_consistency_token_request = (
234+
bigtable_table_admin.GenerateConsistencyTokenRequest(
235+
name=request.name,
236+
)
237+
)
238+
239+
generate_consistency_response = await self.generate_consistency_token(
240+
generate_consistency_token_request,
241+
retry=retry,
242+
timeout=timeout,
243+
metadata=metadata,
244+
)
245+
246+
# Create the CheckConsistencyRequest object.
247+
check_consistency_request = bigtable_table_admin.CheckConsistencyRequest(
248+
name=request.name,
249+
consistency_token=generate_consistency_response.consistency_token,
250+
)
251+
252+
# Since the default values of StandardReadRemoteWrites and DataBoostReadLocalWrites evaluate to
253+
# False in proto plus, we cannot do a simple "if request.standard_read_remote_writes" to check
254+
# whether or not that field is defined in the original request object.
255+
mode_oneof_field = request._pb.WhichOneof("mode")
256+
if mode_oneof_field:
257+
setattr(
258+
check_consistency_request,
259+
mode_oneof_field,
260+
getattr(request, mode_oneof_field),
261+
)
262+
263+
check_consistency_call = functools.partial(
217264
self.check_consistency,
218-
request,
219-
name=name,
220-
consistency_token=consistency_token,
265+
check_consistency_request,
266+
retry=retry,
221267
timeout=timeout,
222268
metadata=metadata,
223269
)
224270

225-
return async_consistency.AsyncCheckConsistencyPollingFuture(
226-
api_call,
227-
check_consistency_call_retry=retry
271+
# Block and wait until the polling harness returns True.
272+
check_consistency_future = async_consistency._AsyncCheckConsistencyPollingFuture(
273+
check_consistency_call
228274
)
275+
return (await check_consistency_future.result())
276+

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

Lines changed: 8 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 AsyncCheckConsistencyPollingFuture(async_future.AsyncFuture):
28+
class _AsyncCheckConsistencyPollingFuture(async_future.AsyncFuture):
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
@@ -48,29 +48,26 @@ class AsyncCheckConsistencyPollingFuture(async_future.AsyncFuture):
4848
<google.cloud.bigtable.admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_consistency>`
4949
or :meth:`wait_for_replication
5050
<google.cloud.bigtable.admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_replication>`
51-
polling (google.api_core.retry.Retry): The configuration used for polling.
52-
This parameter controls how often :meth:`done` is polled. If the
53-
``timeout`` argument is specified in the :meth:`result
54-
<google.api_core.future.polling.PollingFuture.result>` method it will
55-
override the ``polling.timeout`` property.
51+
retry (google.api_core.retry.Retry): The retry configuration used
52+
when polling. This can be used to control how often :meth:`done`
53+
is polled. Regardless of the retry's ``deadline``, it will be
54+
overridden by the ``timeout`` argument to :meth:`result`.
5655
"""
5756

5857
def __init__(
5958
self,
6059
check_consistency_call: Callable[
6160
[OptionalRetry], Awaitable[bigtable_table_admin.CheckConsistencyResponse]
6261
],
63-
check_consistency_call_retry: OptionalRetry = gapic_v1.method.DEFAULT,
64-
future_retry: retries.Retry = async_future.DEFAULT_RETRY,
62+
retry: retries.Retry = async_future.DEFAULT_RETRY,
6563
**kwargs
6664
):
67-
super(AsyncCheckConsistencyPollingFuture, self).__init__(retry=future_retry, **kwargs)
65+
super(_AsyncCheckConsistencyPollingFuture, self).__init__(retry=retry, **kwargs)
6866

6967
# Done is called with two different scenarios, retry is specified or not specified.
7068
# API_call will be a functools partial with everything except retry specified because of
7169
# that.
7270
self._check_consistency_call = check_consistency_call
73-
self._check_consistency_call_retry = check_consistency_call_retry
7471

7572
async def done(self, retry: OptionalRetry = None):
7673
"""Polls the underlying `check_consistency` call to see if the future is complete.
@@ -91,10 +88,8 @@ async def done(self, retry: OptionalRetry = None):
9188
if self._future.done():
9289
return True
9390

94-
retry = retry or self._check_consistency_call_retry
95-
9691
try:
97-
check_consistency_response = await self._check_consistency_call(retry=retry)
92+
check_consistency_response = await self._check_consistency_call()
9893
if check_consistency_response.consistent:
9994
self.set_result(True)
10095

0 commit comments

Comments
 (0)