Skip to content

Commit b508ce7

Browse files
committed
Merge 'feat/vector-retry' into 'master'
feat: add retry and Ping See merge request: !16
2 parents ef073d8 + 485443b commit b508ce7

10 files changed

+55
-31
lines changed

examples/memory/04_exception_handling_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,3 @@ def add_session_exception():
6363
print("Viking Memory Add Session Messages Example\n")
6464

6565
add_session_exception()
66-

examples/vector/E3_1_index_search_multimodal_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_snippet_index_search_multimodal() -> None:
6969
for payload in chapters:
7070
collection_client.upsert(UpsertDataRequest(data=[payload]))
7171

72-
time.sleep(3)
72+
time.sleep(2)
7373

7474
filter_map = {"op": "range", "field": "paragraph", "gte": base_paragraph, "lte": base_paragraph + 1}
7575
search_req = SearchByMultiModalRequest(
@@ -102,7 +102,7 @@ def test_scenario_index_search_multimodal(multimodal_clients: Clients) -> None:
102102
request_options=request_options,
103103
)
104104

105-
time.sleep(3)
105+
time.sleep(2)
106106

107107
filters = bool_and_filters(
108108
[

examples/vector/E3_2_index_search_vector_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def test_v_snippet_index_search_vector() -> None:
9090
payload.append({**chapter, "vector": vector})
9191
collection_client.upsert(UpsertDataRequest(data=payload))
9292

93-
time.sleep(3)
93+
time.sleep(2)
9494

9595
query_req = EmbeddingRequest(
9696
data=[{"text": "Show me the chapter that demonstrates embedding reuse for query vectors."}],
@@ -144,7 +144,7 @@ def test_scenario_index_search_vector(vector_clients: Clients) -> None:
144144
)
145145
vector_clients.collection.upsert(UpsertDataRequest(data=payload), request_options=request_options)
146146

147-
time.sleep(3)
147+
time.sleep(2)
148148

149149
retrieval = next(ch for ch in chapters if ch.key == "retrieval-lab")
150150
query_vector = embed_dense_vectors(

examples/vector/E3_3_search_by_keyword_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_snippet_search_keywords() -> None:
6868
for doc in documents:
6969
collection_client.upsert(UpsertDataRequest(data=[doc]))
7070

71-
time.sleep(3)
71+
time.sleep(2)
7272

7373
filter_map = {"op": "range", "field": "paragraph", "gte": base_paragraph, "lt": base_paragraph + len(documents)}
7474
search_req = SearchByKeywordsRequest(
@@ -90,6 +90,7 @@ def keyword_clients() -> Clients:
9090
def test_scenario_search_keywords(keyword_clients: Clients) -> None:
9191
session_tag = new_session_tag("index-extensions")
9292
request_options = build_request_options(session_tag)
93+
request_options.max_attempts = 5
9394
base_paragraph = int(time.time()) % 1_000_000
9495
chapters = build_story_chapters(session_tag, base_paragraph)
9596

@@ -100,7 +101,7 @@ def test_scenario_search_keywords(keyword_clients: Clients) -> None:
100101
request_options=request_options,
101102
)
102103

103-
time.sleep(5)
104+
time.sleep(2)
104105

105106
filter_map = session_paragraph_bounds(base_paragraph, len(chapters))
106107
search_req = SearchByKeywordsRequest(

examples/vector/E4_search_aggregate_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def test_scenario_search_extensions_and_analytics(aggregate_clients: Clients) ->
9191
request_options=request_options,
9292
)
9393

94-
time.sleep(3)
94+
time.sleep(2)
9595

9696
agg_req = AggRequest(
9797
field="paragraph",

examples/vector/E6_exception_handling_test.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
from vikingdb import IAM
88
from vikingdb.exceptions import NETWORK_ERROR_CODE
9-
from vikingdb.vector import SearchByRandomRequest, VikingVector
10-
from vikingdb.vector.exceptions import VikingVectorException
9+
from vikingdb.vector import VikingVector
10+
from vikingdb.vector.exceptions import VikingVectorException, VikingConnectionException
1111

1212
from .guide_helpers import EnvConfig, load_config
1313

@@ -51,17 +51,7 @@ def test_exception_collection_not_exist() -> None:
5151

5252
def test_exception_wrong_host_raises_network() -> None:
5353
"""Using an invalid host should raise a network exception promoted to VikingVectorException."""
54-
config, client = _build_vector_client(host_override="this-host-does-not-exist.invalid", timeout=1)
55-
56-
index_client = client.index(
57-
collection_name=config.collection,
58-
index_name=config.index,
59-
project_name=config.project_name,
60-
resource_id=config.resource_id,
61-
)
62-
63-
with pytest.raises(VikingVectorException) as exc_info:
64-
index_client.search_by_random(SearchByRandomRequest(limit=1))
65-
66-
error_code = str(exc_info.value.code)
67-
assert "InternalServerError" in error_code
54+
with pytest.raises(VikingConnectionException) as exc_info:
55+
_build_vector_client(host_override="in-v-alid.io", timeout=1)
56+
57+
assert exc_info

vikingdb/_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def _build_service_info(
8181
def prepare_request(self, api_info: ApiInfo, params: Optional[Mapping[str, Any]], doseq: int = 0):
8282
"""Prepare a volcengine request without adding implicit headers."""
8383
request = Request()
84-
request.set_shema(self.service_info.scheme)
84+
request.set_schema(self.service_info.scheme)
8585
request.set_method(api_info.method)
8686
request.set_host(self.service_info.host)
8787
request.set_path(api_info.path)

vikingdb/vector/client.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import annotations
55

66
import json
7+
import time
78
from collections.abc import Mapping
89
from typing import TYPE_CHECKING, Any, Optional
910

@@ -12,7 +13,7 @@
1213
from .._client import Client, _REQUEST_ID_HEADER
1314
from ..auth import Auth
1415
from ..exceptions import VikingException
15-
from .exceptions import VikingVectorException
16+
from .exceptions import VikingVectorException, VikingConnectionException
1617
from ..request_options import RequestOptions, ensure_request_options
1718
from ..version import __version__
1819
from .models import CollectionMeta, IndexMeta
@@ -64,6 +65,12 @@ def __init__(
6465
scheme=scheme,
6566
timeout=timeout,
6667
)
68+
try:
69+
resp = self.session.get(f"{scheme}://{host}/api/vikingdb/Ping")
70+
if resp.status_code != 200:
71+
raise VikingConnectionException(f"failed to ping {host}", f"{resp.status_code}")
72+
except Exception as exp:
73+
raise VikingConnectionException(f"failed to ping {host} ", str(exp))
6774

6875
def collection(
6976
self,
@@ -112,6 +119,13 @@ def request(
112119
options: Optional[RequestOptions] = None,
113120
) -> Mapping[str, object]:
114121
request_options = ensure_request_options(options)
122+
max_attempts = (
123+
request_options.max_attempts
124+
if request_options.max_attempts and request_options.max_attempts > 0
125+
else 3
126+
)
127+
initial_delay_seconds = 0.5
128+
max_delay_seconds = 8.0
115129
headers = {
116130
"Accept": "application/json",
117131
"Content-Type": "application/json",
@@ -124,10 +138,26 @@ def request(
124138

125139
body = json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
126140
params = dict(request_options.query) if request_options.query else None
127-
response_data = self.json_exception(api, params, body, headers=headers, timeout=request_options.timeout)
128-
if not response_data:
129-
return {}
130-
return response_data
141+
for attempt in range(1, max_attempts + 1):
142+
try:
143+
response_data = self.json_exception(
144+
api,
145+
params,
146+
body,
147+
headers=headers,
148+
timeout=request_options.timeout,
149+
)
150+
if not response_data:
151+
return {}
152+
return response_data
153+
except Exception:
154+
if attempt >= max_attempts:
155+
raise
156+
delay = min(
157+
initial_delay_seconds * (2 ** (attempt - 1)),
158+
max_delay_seconds,
159+
)
160+
time.sleep(delay)
131161

132162
def json_exception(
133163
self,

vikingdb/vector/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
from ..exceptions import VikingException
99

10+
class VikingConnectionException(Exception):
11+
def __init__(self, msg: str, cause: str) -> None:
12+
super().__init__(msg, cause)
13+
1014

1115
class VikingVectorException(VikingException):
1216
"""Raised when the remote VikingDB service returns an error payload."""

vikingdb/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
__version__ = '0.1.0'
4+
__version__ = '0.1.1'

0 commit comments

Comments
 (0)