@@ -16,6 +16,7 @@ import { SyncLockLostException, type SyncRunLease } from '@/lib/knowledge/connec
1616import {
1717 addDocument ,
1818 type KnowledgeBaseOwner ,
19+ type PersistedDocument ,
1920 persistSkippedDocuments ,
2021 persistSkippedRetryHashes ,
2122 type SyncDocumentAccess ,
@@ -1497,9 +1498,13 @@ export interface ProcessDocOpsInput {
14971498 hydration : DocOpHydration
14981499 lease : Pick < SyncRunLease , 'beatIfDue' | 'beatLive' | 'stillHeld' >
14991500 /**
1500- * Runs after each batch's rows are written, with the documents that landed.
1501- * A members-mode run grants access here, batch by batch, so a long first
1502- * crawl becomes searchable as it goes rather than all at once at the end.
1501+ * Runs after each batch is written and dispatched, with every row that
1502+ * landed: hydrated documents and skipped ones alike. A members-mode run
1503+ * grants access here, batch by batch, so a long first crawl becomes
1504+ * searchable as it goes rather than all at once at the end. Best effort: a
1505+ * failure here is logged and the run continues, because the listing's own
1506+ * pass at the end of the run writes the same grants authoritatively; only a
1507+ * lost lease ends the run.
15031508 */
15041509 onBatchPersisted ?: ( persisted : readonly PersistedDocument [ ] ) => Promise < void >
15051510 /** Who may read the documents this pass writes. */
@@ -1513,12 +1518,6 @@ export interface ProcessDocOpsInput {
15131518 * run so the connector backs off, and a lost lease, which ends it so no
15141519 * further write lands beside the replacement run's.
15151520 */
1516- /** A document a batch wrote, by the id the source knows it by and the id the row has. */
1517- export interface PersistedDocument {
1518- externalId : string
1519- documentId : string
1520- }
1521-
15221521export async function processDocOps ( input : ProcessDocOpsInput ) : Promise < void > {
15231522 const {
15241523 connectorId,
@@ -1689,6 +1688,7 @@ export async function processDocOps(input: ProcessDocOpsInput): Promise<void> {
16891688 }
16901689 }
16911690
1691+ const skippedPersisted : PersistedDocument [ ] = [ ]
16921692 if ( skipOps . length > 0 ) {
16931693 try {
16941694 const recorded = await persistSkippedDocuments (
@@ -1700,7 +1700,8 @@ export async function processDocOps(input: ProcessDocOpsInput): Promise<void> {
17001700 documentAccess ,
17011701 input . lease
17021702 )
1703- result . docsSkipped += recorded
1703+ result . docsSkipped += recorded . length
1704+ skippedPersisted . push ( ...recorded )
17041705 } catch ( error ) {
17051706 if ( error instanceof SyncLockLostException ) throw error
17061707 /**
@@ -1756,7 +1757,7 @@ export async function processDocOps(input: ProcessDocOpsInput): Promise<void> {
17561757 if ( leaseLost ) throw leaseLost . reason
17571758
17581759 const batchDocs : DocumentData [ ] = [ ]
1759- const persisted : PersistedDocument [ ] = [ ]
1760+ const persisted : PersistedDocument [ ] = [ ... skippedPersisted ]
17601761 for ( let j = 0 ; j < settled . length ; j ++ ) {
17611762 const outcome = settled [ j ]
17621763 if ( outcome . status === 'fulfilled' ) {
@@ -1778,8 +1779,6 @@ export async function processDocOps(input: ProcessDocOpsInput): Promise<void> {
17781779 }
17791780 }
17801781
1781- if ( persisted . length > 0 ) await input . onBatchPersisted ?.( persisted )
1782-
17831782 if ( batchDocs . length > 0 ) {
17841783 result . processingDispatch . requested += batchDocs . length
17851784 try {
@@ -1803,6 +1802,19 @@ export async function processDocOps(input: ProcessDocOpsInput): Promise<void> {
18031802 } )
18041803 }
18051804 }
1805+
1806+ if ( persisted . length > 0 && input . onBatchPersisted ) {
1807+ try {
1808+ await input . onBatchPersisted ( persisted )
1809+ } catch ( error ) {
1810+ if ( error instanceof SyncLockLostException ) throw error
1811+ logger . warn ( 'Failed to grant access for a persisted batch — the run end will retry' , {
1812+ connectorId,
1813+ count : persisted . length ,
1814+ error : toError ( error ) . message ,
1815+ } )
1816+ }
1817+ }
18061818 }
18071819}
18081820
0 commit comments