Skip to content

Commit 9f5ea99

Browse files
authored
Add --concurrency-timeout option to avoid long time waiting (zilliztech#521)
* Add --concurrency-timeout option to avoid long time waiting, by default, it's 3600s. * Fix lint error * Update README.md, add --concurrency-timeout option
1 parent 4efbe83 commit 9f5ea99

6 files changed

Lines changed: 43 additions & 8 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ Options:
114114
--num-concurrency TEXT Comma-separated list of concurrency values
115115
to test during concurrent search [default:
116116
1,10,20]
117+
--concurrency-timeout INTEGER Timeout (in seconds) to wait for a
118+
concurrency slot before failing. Set to a
119+
negative value to wait indefinitely.
120+
[default: 3600]
117121
--user-name TEXT Db username [required]
118122
--password TEXT Db password [required]
119123
--host TEXT Db host [required]

vectordb_bench/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from . import log_util
77

88
env = environs.Env()
9-
env.read_env(".env", False)
9+
env.read_env(path=".env", recurse=False)
1010

1111

1212
class config:
@@ -52,6 +52,8 @@ class config:
5252

5353
CONCURRENCY_DURATION = 30
5454

55+
CONCURRENCY_TIMEOUT = 3600
56+
5557
RESULTS_LOCAL_DIR = env.path(
5658
"RESULTS_LOCAL_DIR",
5759
pathlib.Path(__file__).parent.joinpath("results"),

vectordb_bench/backend/runner/mp_runner.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import time
66
import traceback
77
from collections.abc import Iterable
8+
from multiprocessing.queues import Queue
89

910
import numpy as np
1011

1112
from ... import config
13+
from ...models import ConcurrencySlotTimeoutError
1214
from ..clients import api
1315

1416
NUM_PER_BATCH = config.NUM_PER_BATCH
@@ -28,16 +30,18 @@ def __init__(
2830
self,
2931
db: api.VectorDB,
3032
test_data: list[list[float]],
31-
k: int = 100,
33+
k: int = config.K_DEFAULT,
3234
filters: dict | None = None,
3335
concurrencies: Iterable[int] = config.NUM_CONCURRENCY,
34-
duration: int = 30,
36+
duration: int = config.CONCURRENCY_DURATION,
37+
concurrency_timeout: int = config.CONCURRENCY_TIMEOUT,
3538
):
3639
self.db = db
3740
self.k = k
3841
self.filters = filters
3942
self.concurrencies = concurrencies
4043
self.duration = duration
44+
self.concurrency_timeout = concurrency_timeout
4145

4246
self.test_data = test_data
4347
log.debug(f"test dataset columns: {len(test_data)}")
@@ -114,9 +118,7 @@ def _run_all_concurrencies_mem_efficient(self):
114118
log.info(f"Start search {self.duration}s in concurrency {conc}, filters: {self.filters}")
115119
future_iter = [executor.submit(self.search, self.test_data, q, cond) for i in range(conc)]
116120
# Sync all processes
117-
while q.qsize() < conc:
118-
sleep_t = conc if conc < 10 else 10
119-
time.sleep(sleep_t)
121+
self._wait_for_queue_fill(q, size=conc)
120122

121123
with cond:
122124
cond.notify_all()
@@ -160,6 +162,15 @@ def _run_all_concurrencies_mem_efficient(self):
160162
conc_latency_avg_list,
161163
)
162164

165+
def _wait_for_queue_fill(self, q: Queue, size: int):
166+
wait_t = 0
167+
while q.qsize() < size:
168+
sleep_t = size if size < 10 else 10
169+
wait_t += sleep_t
170+
if wait_t > self.concurrency_timeout > 0:
171+
raise ConcurrencySlotTimeoutError
172+
time.sleep(sleep_t)
173+
163174
def run(self) -> float:
164175
"""
165176
Returns:

vectordb_bench/backend/task_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ def _init_search_runner(self):
275275
filters=self.ca.filters,
276276
concurrencies=self.config.case_config.concurrency_search_config.num_concurrency,
277277
duration=self.config.case_config.concurrency_search_config.concurrency_duration,
278+
concurrency_timeout=self.config.case_config.concurrency_search_config.concurrency_timeout,
278279
k=self.config.case_config.k,
279280
)
280281

vectordb_bench/cli/cli.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@
1717
import click
1818
from yaml import load
1919

20-
from vectordb_bench.backend.clients.api import MetricType
21-
2220
from .. import config
2321
from ..backend.clients import DB
22+
from ..backend.clients.api import MetricType
2423
from ..interface import benchmark_runner, global_result_future
2524
from ..models import (
2625
CaseConfig,
@@ -303,6 +302,17 @@ class CommonTypedDict(TypedDict):
303302
callback=lambda *args: list(map(int, click_arg_split(*args))),
304303
),
305304
]
305+
concurrency_timeout: Annotated[
306+
int,
307+
click.option(
308+
"--concurrency-timeout",
309+
type=int,
310+
default=config.CONCURRENCY_TIMEOUT,
311+
show_default=True,
312+
help="Timeout (in seconds) to wait for a concurrency slot before failing. "
313+
"Set to a negative value to wait indefinitely.",
314+
),
315+
]
306316
custom_case_name: Annotated[
307317
str,
308318
click.option(
@@ -490,6 +500,7 @@ def run(
490500
concurrency_search_config=ConcurrencySearchConfig(
491501
concurrency_duration=parameters["concurrency_duration"],
492502
num_concurrency=[int(s) for s in parameters["num_concurrency"]],
503+
concurrency_timeout=parameters["concurrency_timeout"],
493504
),
494505
custom_case=get_custom_case_config(parameters),
495506
),

vectordb_bench/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ def __init__(self):
3030
super().__init__("Performance case optimize timeout")
3131

3232

33+
class ConcurrencySlotTimeoutError(TimeoutError):
34+
def __init__(self):
35+
super().__init__("Timeout while waiting for a concurrency slot to become available")
36+
37+
3338
class CaseConfigParamType(Enum):
3439
"""
3540
Value will be the key of CaseConfig.params and displayed in UI
@@ -113,6 +118,7 @@ class CustomizedCase(BaseModel):
113118
class ConcurrencySearchConfig(BaseModel):
114119
num_concurrency: list[int] = config.NUM_CONCURRENCY
115120
concurrency_duration: int = config.CONCURRENCY_DURATION
121+
concurrency_timeout: int = config.CONCURRENCY_TIMEOUT
116122

117123

118124
class CaseConfig(BaseModel):

0 commit comments

Comments
 (0)