Skip to content

Commit 6cc890b

Browse files
fix(bigtable): ensure deadline is respected for read_rows_sharded (googleapis#17352)
The read_rows_sharded tests were flaky. It seems this mostly came down to not having a mutex on the timeout generator, which isn't completely thread safe in the sync context. This ensures that the timeout is always accessed sequentially Also increase the timeout in the test, to prevent future flakes
1 parent 8b8ac0a commit 6cc890b

4 files changed

Lines changed: 12 additions & 7 deletions

File tree

packages/google-cloud-bigtable/google/cloud/bigtable/data/_async/client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,12 +1286,15 @@ async def read_rows_sharded(
12861286

12871287
# limit the number of concurrent requests using a semaphore
12881288
concurrency_sem = CrossSync.Semaphore(_CONCURRENCY_LIMIT)
1289+
# lock to ensure rpc_timeout_generator is thread-safe in sync version
1290+
gen_lock = CrossSync.Semaphore(1)
12891291

12901292
@CrossSync.convert
12911293
async def read_rows_with_semaphore(query):
12921294
async with concurrency_sem:
1293-
# calculate new timeout based on time left in overall operation
1294-
shard_timeout = next(rpc_timeout_generator)
1295+
async with gen_lock:
1296+
# calculate new timeout based on time left in overall operation
1297+
shard_timeout = next(rpc_timeout_generator)
12951298
if shard_timeout <= 0:
12961299
raise DeadlineExceeded(
12971300
"Operation timeout exceeded before starting query"

packages/google-cloud-bigtable/google/cloud/bigtable/data/_sync_autogen/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,10 +1049,12 @@ def read_rows_sharded(
10491049
operation_timeout, operation_timeout
10501050
)
10511051
concurrency_sem = CrossSync._Sync_Impl.Semaphore(_CONCURRENCY_LIMIT)
1052+
gen_lock = CrossSync._Sync_Impl.Semaphore(1)
10521053

10531054
def read_rows_with_semaphore(query):
10541055
with concurrency_sem:
1055-
shard_timeout = next(rpc_timeout_generator)
1056+
with gen_lock:
1057+
shard_timeout = next(rpc_timeout_generator)
10561058
if shard_timeout <= 0:
10571059
raise DeadlineExceeded(
10581060
"Operation timeout exceeded before starting query"

packages/google-cloud-bigtable/tests/unit/data/_async/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,7 @@ async def test_read_rows_sharded_expirary(self):
23042304
from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT
23052305
from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup
23062306

2307-
operation_timeout = 0.1
2307+
operation_timeout = 5.0
23082308

23092309
# let the first batch complete, but the next batch times out
23102310
num_queries = 15
@@ -2317,7 +2317,7 @@ async def mock_call(*args, **kwargs):
23172317
if isinstance(next_item, Exception):
23182318
raise next_item
23192319
else:
2320-
await asyncio.sleep(next_item)
2320+
await CrossSync.sleep(next_item)
23212321
return [mock.Mock()]
23222322

23232323
async with self._make_client() as client:

packages/google-cloud-bigtable/tests/unit/data/_sync_autogen/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,7 @@ def test_read_rows_sharded_expirary(self):
19281928
from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT
19291929
from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup
19301930

1931-
operation_timeout = 0.1
1931+
operation_timeout = 5.0
19321932
num_queries = 15
19331933
sleeps = [0] * _CONCURRENCY_LIMIT + [DeadlineExceeded("times up")] * (
19341934
num_queries - _CONCURRENCY_LIMIT
@@ -1939,7 +1939,7 @@ def mock_call(*args, **kwargs):
19391939
if isinstance(next_item, Exception):
19401940
raise next_item
19411941
else:
1942-
asyncio.sleep(next_item)
1942+
CrossSync._Sync_Impl.sleep(next_item)
19431943
return [mock.Mock()]
19441944

19451945
with self._make_client() as client:

0 commit comments

Comments
 (0)