Skip to content

Commit 68fbf80

Browse files
committed
feature #834 Qdrant sync (natewiebe13)
This PR was squashed before being merged into the main branch. Discussion ---------- Qdrant sync | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | no | License | MIT Currently, Qdrant PUT operations are async. This forces the user to add checking after the request happens to determine if it was successful or not. This adds an option to make operations sync so you can handle any errors immediately instead of polling after until the operation completes. Commits ------- 89ed6b8 Qdrant sync
2 parents 78da996 + 89ed6b8 commit 68fbf80

File tree

5 files changed

+62
-11
lines changed

5 files changed

+62
-11
lines changed

src/ai-bundle/config/options.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@
607607
->stringNode('collection_name')->cannotBeEmpty()->end()
608608
->integerNode('dimensions')->end()
609609
->stringNode('distance')->end()
610+
->booleanNode('async')->defaultFalse()->end()
610611
->end()
611612
->end()
612613
->end()

src/ai-bundle/src/AiBundle.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,10 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
11121112
$arguments[5] = $store['distance'];
11131113
}
11141114

1115+
if (\array_key_exists('async', $store)) {
1116+
$arguments[6] = $store['async'];
1117+
}
1118+
11151119
$definition = new Definition(QdrantStore::class);
11161120
$definition
11171121
->addTag('ai.store')

src/ai-bundle/tests/DependencyInjection/AiBundleTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2967,6 +2967,7 @@ private function getFullConfig(): array
29672967
'collection_name' => 'foo',
29682968
'dimensions' => 768,
29692969
'distance' => 'Cosine',
2970+
'async' => false,
29702971
],
29712972
],
29722973
'redis' => [

src/store/src/Bridge/Qdrant/Store.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function __construct(
3333
private readonly string $collectionName,
3434
private readonly int $embeddingsDimension = 1536,
3535
private readonly string $embeddingsDistance = 'Cosine',
36+
private readonly bool $async = false,
3637
) {
3738
}
3839

@@ -58,9 +59,14 @@ public function setup(array $options = []): void
5859

5960
public function add(VectorDocument ...$documents): void
6061
{
61-
$this->request('PUT', \sprintf('collections/%s/points', $this->collectionName), [
62-
'points' => array_map($this->convertToIndexableArray(...), $documents),
63-
]);
62+
$this->request(
63+
'PUT',
64+
\sprintf('collections/%s/points', $this->collectionName),
65+
[
66+
'points' => array_map($this->convertToIndexableArray(...), $documents),
67+
],
68+
['wait' => $this->async ? 'false' : 'true'],
69+
);
6470
}
6571

6672
/**
@@ -102,17 +108,19 @@ public function drop(): void
102108

103109
/**
104110
* @param array<string, mixed> $payload
111+
* @param array<string, mixed> $queryParameters
105112
*
106113
* @return array<string, mixed>
107114
*/
108-
private function request(string $method, string $endpoint, array $payload = []): array
115+
private function request(string $method, string $endpoint, array $payload = [], array $queryParameters = []): array
109116
{
110117
$url = \sprintf('%s/%s', $this->endpointUrl, $endpoint);
111118

112119
$response = $this->httpClient->request($method, $url, [
113120
'headers' => [
114121
'api-key' => $this->apiKey,
115122
],
123+
'query' => $queryParameters,
116124
'json' => $payload,
117125
]);
118126

src/store/tests/Bridge/Qdrant/StoreTest.php

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,52 @@ public function testStoreCannotAddOnInvalidResponse()
145145
$store = new Store($httpClient, 'http://127.0.0.1:6333', 'test', 'test');
146146

147147
$this->expectException(ClientException::class);
148-
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:6333/collections/test/points".');
148+
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:6333/collections/test/points?wait=true".');
149149
$this->expectExceptionCode(400);
150150
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
151151
}
152152

153153
public function testStoreCanAdd()
154154
{
155-
$httpClient = new MockHttpClient([
156-
new JsonMockResponse([
155+
$document = new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]));
156+
157+
$httpClient = new MockHttpClient(static function (string $method, string $url, array $options) use ($document): JsonMockResponse {
158+
self::assertArrayHasKey('wait', $options['query']);
159+
self::assertEquals('true', $options['query']['wait']);
160+
161+
return new JsonMockResponse([
162+
'time' => 0.002,
163+
'status' => 'ok',
164+
'result' => [
165+
'points' => [
166+
[
167+
'id' => (string) $document->id,
168+
'payload' => (array) $document->metadata,
169+
'vector' => $document->vector->getData(),
170+
],
171+
],
172+
],
173+
], [
174+
'http_code' => 200,
175+
]);
176+
}, 'http://127.0.0.1:6333');
177+
178+
$store = new Store($httpClient, 'http://127.0.0.1:6333', 'test', 'test');
179+
180+
$store->add($document);
181+
182+
$this->assertSame(1, $httpClient->getRequestsCount());
183+
}
184+
185+
public function testStoreCanAddAsynchronously()
186+
{
187+
$document = new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]));
188+
189+
$httpClient = new MockHttpClient(static function (string $method, string $url, array $options): JsonMockResponse {
190+
self::assertArrayHasKey('wait', $options['query']);
191+
self::assertEquals('false', $options['query']['wait']);
192+
193+
return new JsonMockResponse([
157194
'time' => 0.002,
158195
'status' => 'ok',
159196
'result' => [
@@ -162,12 +199,12 @@ public function testStoreCanAdd()
162199
],
163200
], [
164201
'http_code' => 200,
165-
]),
166-
], 'http://127.0.0.1:6333');
202+
]);
203+
}, 'http://127.0.0.1:6333');
167204

168-
$store = new Store($httpClient, 'http://127.0.0.1:6333', 'test', 'test');
205+
$store = new Store($httpClient, 'http://127.0.0.1:6333', 'test', 'test', async: true);
169206

170-
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
207+
$store->add($document);
171208

172209
$this->assertSame(1, $httpClient->getRequestsCount());
173210
}

0 commit comments

Comments
 (0)