doc2vec 2.10.4 → 2.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/database.js +79 -46
- package/package.json +1 -1
package/dist/database.js
CHANGED
|
@@ -215,7 +215,13 @@ class DatabaseManager {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
catch (error) {
|
|
218
|
-
|
|
218
|
+
// Best-effort by design: a failed metadata write errs toward the
|
|
219
|
+
// safe direction (redundant reprocessing next run — etag/lastmod/
|
|
220
|
+
// watermark stay behind, never skip ahead), so we warn rather than
|
|
221
|
+
// fail the job. Genuine disk/connection failures surface earlier at
|
|
222
|
+
// the chunk-write stage (storeChunkInQdrant), which shares this
|
|
223
|
+
// collection and throws.
|
|
224
|
+
logger.warn(`Failed to update metadata value for ${key} (continuing; will retry next run):`, error);
|
|
219
225
|
}
|
|
220
226
|
}
|
|
221
227
|
static async getLastRunDate(dbConnection, repo, defaultDate, logger) {
|
|
@@ -436,7 +442,11 @@ class DatabaseManager {
|
|
|
436
442
|
});
|
|
437
443
|
}
|
|
438
444
|
catch (error) {
|
|
439
|
-
|
|
445
|
+
// Rethrow so the failure propagates to the top-level handler and the
|
|
446
|
+
// job exits non-zero. Swallowing here previously let a sync "succeed"
|
|
447
|
+
// while chunks silently failed to store (e.g. Qdrant disk full).
|
|
448
|
+
console.error(`Error storing chunk in Qdrant (collection ${collectionName}, url ${chunk.metadata.url}):`, error);
|
|
449
|
+
throw error;
|
|
440
450
|
}
|
|
441
451
|
}
|
|
442
452
|
static removeObsoleteChunksSQLite(db, visitedUrls, urlPrefix, logger) {
|
|
@@ -518,7 +528,11 @@ class DatabaseManager {
|
|
|
518
528
|
}
|
|
519
529
|
}
|
|
520
530
|
catch (error) {
|
|
531
|
+
// Rethrow so a failed cleanup fails the job instead of silently
|
|
532
|
+
// leaving orphans behind. This is idempotent and recomputed each
|
|
533
|
+
// run, so a rerun retries it cleanly.
|
|
521
534
|
logger.error(`Error removing obsolete chunks from Qdrant:`, error);
|
|
535
|
+
throw error;
|
|
522
536
|
}
|
|
523
537
|
}
|
|
524
538
|
static hasColumn(db, columnName) {
|
|
@@ -561,7 +575,12 @@ class DatabaseManager {
|
|
|
561
575
|
logger.info(`Deleted chunks from Qdrant for URL ${url}`);
|
|
562
576
|
}
|
|
563
577
|
catch (error) {
|
|
578
|
+
// Rethrow so the failure propagates and the job exits non-zero.
|
|
579
|
+
// A swallowed delete leaves stale chunks behind while the sync
|
|
580
|
+
// reports success. Callers that treat deletion as best-effort
|
|
581
|
+
// (e.g. 404 cleanup) wrap this call in their own try/catch.
|
|
564
582
|
logger.error(`Error deleting chunks from Qdrant for URL ${url}:`, error);
|
|
583
|
+
throw error;
|
|
565
584
|
}
|
|
566
585
|
}
|
|
567
586
|
/**
|
|
@@ -726,53 +745,64 @@ class DatabaseManager {
|
|
|
726
745
|
urlPrefix = `file://${cleanedDirPrefix}`;
|
|
727
746
|
}
|
|
728
747
|
logger.debug(`Checking for obsolete chunks with URL prefix: ${urlPrefix}`);
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
748
|
+
// Scroll through ALL matching points via next_page_offset. A single
|
|
749
|
+
// capped scroll would only examine the first page, so obsolete
|
|
750
|
+
// chunks beyond it (in collections larger than the page limit) would
|
|
751
|
+
// never be removed.
|
|
752
|
+
const filter = {
|
|
753
|
+
must: [
|
|
754
|
+
{
|
|
755
|
+
key: "url",
|
|
756
|
+
match: {
|
|
757
|
+
text: urlPrefix
|
|
740
758
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
759
|
+
}
|
|
760
|
+
],
|
|
761
|
+
must_not: [
|
|
762
|
+
{
|
|
763
|
+
key: "is_metadata",
|
|
764
|
+
match: {
|
|
765
|
+
value: true
|
|
748
766
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
const obsoletePointIds =
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
//
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
filePath
|
|
767
|
+
}
|
|
768
|
+
]
|
|
769
|
+
};
|
|
770
|
+
const obsoletePointIds = [];
|
|
771
|
+
let offset = undefined;
|
|
772
|
+
do {
|
|
773
|
+
const response = await client.scroll(collectionName, {
|
|
774
|
+
limit: 1000,
|
|
775
|
+
offset,
|
|
776
|
+
with_payload: true,
|
|
777
|
+
with_vector: false,
|
|
778
|
+
filter
|
|
779
|
+
});
|
|
780
|
+
for (const point of response.points) {
|
|
781
|
+
const url = point.payload?.url;
|
|
782
|
+
// Double check it's not a metadata record
|
|
783
|
+
if (point.payload?.is_metadata === true) {
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
if (!url || !url.startsWith(urlPrefix)) {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
let filePath;
|
|
790
|
+
if (isRewriteMode) {
|
|
791
|
+
// URL rewrite mode: extract relative path and construct full file path
|
|
792
|
+
const config = pathConfig;
|
|
793
|
+
const relativePath = url.substring(urlPrefix.length + 1); // +1 for the '/'
|
|
794
|
+
filePath = path.join(config.path, relativePath);
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
// Direct file path mode: remove file:// prefix to match with processedFiles
|
|
798
|
+
filePath = url.startsWith('file://') ? url.substring(7) : '';
|
|
799
|
+
}
|
|
800
|
+
if (filePath && !processedFiles.has(filePath)) {
|
|
801
|
+
obsoletePointIds.push(point.id);
|
|
802
|
+
}
|
|
772
803
|
}
|
|
773
|
-
|
|
774
|
-
})
|
|
775
|
-
.map((point) => point.id);
|
|
804
|
+
offset = response.next_page_offset;
|
|
805
|
+
} while (offset !== null && offset !== undefined);
|
|
776
806
|
if (obsoletePointIds.length > 0) {
|
|
777
807
|
await client.delete(collectionName, {
|
|
778
808
|
points: obsoletePointIds,
|
|
@@ -784,7 +814,10 @@ class DatabaseManager {
|
|
|
784
814
|
}
|
|
785
815
|
}
|
|
786
816
|
catch (error) {
|
|
817
|
+
// Rethrow so a failed cleanup fails the job instead of silently
|
|
818
|
+
// leaving orphans behind (idempotent — retried cleanly next run).
|
|
787
819
|
logger.error(`Error removing obsolete chunks from Qdrant:`, error);
|
|
820
|
+
throw error;
|
|
788
821
|
}
|
|
789
822
|
}
|
|
790
823
|
}
|