Skip to content

Commit

Permalink
Do not throw ResourceQuotaExceeded
Browse files Browse the repository at this point in the history
  • Loading branch information
tellet-q committed Mar 11, 2025
1 parent b01b99b commit 87bc1a1
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 46 deletions.
8 changes: 0 additions & 8 deletions qdrant_client/common/client_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,3 @@ def __init__(self, message: str, retry_after_s: int) -> None:

def __str__(self) -> str:
return self.message.strip()


class ResourceQuotaExceeded(QdrantException):
def __init__(self, message: str) -> None:
self.message = message if message else "Quota Exceeded Response"

def __str__(self) -> str:
return self.message.strip()
4 changes: 1 addition & 3 deletions qdrant_client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import grpc

from qdrant_client.common.client_exceptions import ResourceExhaustedResponse, ResourceQuotaExceeded
from qdrant_client.common.client_exceptions import ResourceExhaustedResponse


# type: ignore # noqa: F401
Expand Down Expand Up @@ -145,8 +145,6 @@ def process_response(response: Any) -> Any:
reason_phrase = response.details() if response.details() else ""
if retry_after:
raise ResourceExhaustedResponse(message=reason_phrase, retry_after_s=retry_after)
else:
raise ResourceQuotaExceeded(message=reason_phrase)
return response

def intercept_call(
Expand Down
6 changes: 1 addition & 5 deletions qdrant_client/http/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from httpx import AsyncClient, Client, Request, Response
from pydantic import ValidationError
from qdrant_client.common.client_exceptions import ResourceExhaustedResponse, ResourceQuotaExceeded
from qdrant_client.common.client_exceptions import ResourceExhaustedResponse
from qdrant_client.http.api.aliases_api import AsyncAliasesApi, SyncAliasesApi
from qdrant_client.http.api.beta_api import AsyncBetaApi, SyncBetaApi
from qdrant_client.http.api.collections_api import AsyncCollectionsApi, SyncCollectionsApi
Expand Down Expand Up @@ -119,8 +119,6 @@ def send(self, request: Request, type_: Type[T]) -> T:

if retry_after_s:
raise ResourceExhaustedResponse(message, retry_after_s)
else:
raise ResourceQuotaExceeded(message=message)

if response.status_code in [200, 201, 202]:
try:
Expand Down Expand Up @@ -208,8 +206,6 @@ async def send(self, request: Request, type_: Type[T]) -> T:

if retry_after_s:
raise ResourceExhaustedResponse(message, retry_after_s)
else:
raise ResourceQuotaExceeded(message=message)

if response.status_code in [200, 201, 202]:
try:
Expand Down
67 changes: 37 additions & 30 deletions tests/congruence_tests/test_rate_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import numpy as np
import pytest
from grpc import RpcError

from qdrant_client.common.client_exceptions import ResourceQuotaExceeded, ResourceExhaustedResponse
from qdrant_client.common.client_exceptions import ResourceExhaustedResponse
from qdrant_client.http import models
from qdrant_client.http.exceptions import UnexpectedResponse
from tests.congruence_tests.test_common import (
COLLECTION_NAME,
compare_collections,
Expand Down Expand Up @@ -45,13 +47,13 @@ def test_upsert_hits_large_request_limit(remote_client):
)

with pytest.raises(
ResourceQuotaExceeded,
UnexpectedResponse,
match="Write rate limit exceeded, request larger than than rate limiter capacity, please try to split your request",
):
remote_client.upsert(COLLECTION_NAME, points_batch)

with pytest.raises(
ResourceQuotaExceeded,
RpcError,
match="Write rate limit exceeded, request larger than than rate limiter capacity, please try to split your request",
):
grpc_client.upsert(COLLECTION_NAME, points_batch)
Expand Down Expand Up @@ -123,8 +125,39 @@ def test_upsert_hits_write_rate_limit(remote_client):
def test_upload_collection_succeeds_with_limits(local_client, remote_client):
grpc_client = init_remote(prefer_grpc=True)

points = generate_fixtures(10)
remote_client.update_collection(
collection_name=COLLECTION_NAME,
strict_mode_config=models.StrictModeConfig(
enabled=True, read_rate_limit=READ_LIMIT, write_rate_limit=WRITE_LIMIT
),
)

# pre-condition: hit the limit first then do upload_collection
points = generate_fixtures(WRITE_LIMIT)
ids, payload = [], []
vectors = {}
for point in points:
ids.append(point.id)
payload.append(point.payload)
for vector_name, vector in point.vector.items():
if vector_name not in vectors:
vectors[vector_name] = []
vectors[vector_name].append(vector)

points_batch = models.Batch(
ids=ids,
vectors=vectors,
payloads=payload,
)
try:
for _ in range(10):
remote_client.upsert(COLLECTION_NAME, points_batch)
grpc_client.upsert(COLLECTION_NAME, points_batch)
except ResourceExhaustedResponse as ex:
print(ex.message)
# end of pre-condition

points = generate_fixtures(WRITE_LIMIT)
vectors = []
payload = []
ids = []
Expand All @@ -133,13 +166,6 @@ def test_upload_collection_succeeds_with_limits(local_client, remote_client):
vectors.append(point.vector)
payload.append(point.payload)

remote_client.update_collection(
collection_name=COLLECTION_NAME,
strict_mode_config=models.StrictModeConfig(
enabled=True, read_rate_limit=READ_LIMIT, write_rate_limit=WRITE_LIMIT
),
)

local_client.upload_collection(COLLECTION_NAME, vectors, payload, ids=ids)
remote_client.upload_collection(
COLLECTION_NAME, vectors, payload, ids=ids, wait=True, max_retries=1
Expand All @@ -152,25 +178,6 @@ def test_upload_collection_succeeds_with_limits(local_client, remote_client):
compare_collections(local_client, grpc_client, UPLOAD_NUM_VECTORS)


def test_upload_points_succeeds_with_limits(local_client, remote_client):
grpc_client = init_remote(prefer_grpc=True)
points = generate_fixtures(10)

remote_client.update_collection(
collection_name=COLLECTION_NAME,
strict_mode_config=models.StrictModeConfig(
enabled=True, read_rate_limit=READ_LIMIT, write_rate_limit=WRITE_LIMIT
),
)

local_client.upload_points(COLLECTION_NAME, points)
remote_client.upload_points(COLLECTION_NAME, points, wait=True, max_retries=1)
grpc_client.upload_points(COLLECTION_NAME, points, wait=True, max_retries=1)

compare_collections(local_client, remote_client, UPLOAD_NUM_VECTORS)
compare_collections(local_client, grpc_client, UPLOAD_NUM_VECTORS)


def test_query_hits_read_rate_limit(remote_client):
grpc_client = init_remote(prefer_grpc=True)

Expand Down

0 comments on commit 87bc1a1

Please sign in to comment.