Call ``Commit`` on the GAPIC client with retry / sleep.

    Retries the ``Commit`` RPC on Unavailable. Usually this RPC-level
    retry is handled by the underlying GAPICd client, but in this case it
    doesn't because ``Commit`` is not always idempotent. But here we know it
    is "idempotent"-like because it has a transaction ID. We also need to do
    our own retry to special-case the ``INVALID_ARGUMENT`` error.

    Args:
        client (~.firestore_v1beta1.client.Client): A client with
            GAPIC client and configuration details.
        write_pbs (List[google.cloud.proto.firestore.v1beta1.\
            write_pb2.Write, ...]): A ``Write`` protobuf instance to
            be committed.
        transaction_id (bytes): ID of an existing transaction that
            this commit will run in.

    Returns:
        google.cloud.firestore_v1beta1.types.CommitResponse:
        The protobuf response from ``Commit``.

    Raises:
        ~google.api_core.exceptions.GoogleAPICallError: If a non-retryable
            exception is encountered.

def _commit_with_retry(client, write_pbs, transaction_id):
    """Call ``Commit`` on the GAPIC client with retry / sleep.

    Retries the ``Commit`` RPC on Unavailable. Usually this RPC-level
    retry is handled by the underlying GAPICd client, but in this case it
    doesn't because ``Commit`` is not always idempotent. But here we know it
    is "idempotent"-like because it has a transaction ID. We also need to do
    our own retry to special-case the ``INVALID_ARGUMENT`` error.

    Args:
        client (~.firestore_v1beta1.client.Client): A client with
            GAPIC client and configuration details.
        write_pbs (List[google.cloud.proto.firestore.v1beta1.\
            write_pb2.Write, ...]): A ``Write`` protobuf instance to
            be committed.
        transaction_id (bytes): ID of an existing transaction that
            this commit will run in.

    Returns:
        google.cloud.firestore_v1beta1.types.CommitResponse:
        The protobuf response from ``Commit``.

    Raises:
        ~google.api_core.exceptions.GoogleAPICallError: If a non-retryable
            exception is encountered.
    """
    current_sleep = _INITIAL_SLEEP
    while True:
        try:
            return client._firestore_api.commit(
                client._database_string,
                write_pbs,
                transaction=transaction_id,
                metadata=client._rpc_metadata,
            )
        except exceptions.ServiceUnavailable:
            # Retry
            pass

        current_sleep = _sleep(current_sleep)