экспоненциальный откат для пакетного удаления объектов в клиенте Python - PullRequest
0 голосов
/ 13 сентября 2018

мой запрос выглядит как Пакетный запрос с Python-клиентом Google Cloud Storage

blobs_to_delete = [blob for blob in bucket.list_blobs(prefix="my/prefix/here")]

    for c in _chunk(blobs, batch_size=100):
        with storage_client.batch():
            for blob in c:
                blob.delete()

ошибка:

[2018-09-12 21:28:41,726] {base_task_runner.py:98} INFO - Subtask:   File "/usr/local/lib/python2.7/site-packages/google/cloud/storage/batch.py", line 243, in _finish_futures
[2018-09-12 21:28:41,731] {base_task_runner.py:98} INFO - Subtask:     raise exceptions.from_http_response(exception_args)
[2018-09-12 21:28:41,731] {base_task_runner.py:98} INFO - Subtask: google.api_core.exceptions.InternalServerError: 500 BATCH contentid://None: Backend Error

Как добавить усеченный экспоненциальный откат к моему коду?

1 Ответ

0 голосов
/ 26 сентября 2018

Код пакета не включает в себя саму повторную попытку и не позволяет вам точно определить, какие запросы изнутри не были выполнены. Это означает, что (а) вы должны будете повторить попытку самостоятельно, и (б) вам придется повторить всю партию.

(a) можно упростить с помощью пакета retrying. (б) не проблема, так как удаление капли идемпотентно.

В совокупности решение может выглядеть следующим образом:

def retriable_exception(e):
    return isinstance(e, GoogleAPICallError) and (e.code == 429 or e.code>=500)

@retry(retry_on_exception=retriable_exception,
       stop_max_attempt_number=7,
       wait_exponential_multiplier=1000,
       wait_exponential_max=10000)
def delete_batch(c):
    with storage_client.batch():
        for blob in c:
            blob.delete()

blobs_to_delete = [blob for blob in bucket.list_blobs(prefix="my/prefix/here")]

for c in _chunk(blobs, batch_size=100):
    delete_batch(c)
...