Skip to content

Commit 86ca393

Browse files
committed
sharding: complete tenant-routed data and recovery paths
1 parent f56be9b commit 86ca393

6 files changed

Lines changed: 36 additions & 284 deletions

File tree

src/main/java/com/veriprotocol/springAI/core/DocumentService.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ public void afterCommit() {
219219
);
220220

221221
markPublishFailed(
222+
tenantId,
222223
docId,
223224
safeMsg(ex)
224225
);
@@ -254,8 +255,16 @@ public void afterCommit() {
254255

255256
return existing.id();
256257
}
257-
private void markPublishFailed(String docId, String err) {
258-
docRepo.updateLastError(docId, "PUBLISH_FAILED: " + err);
258+
private void markPublishFailed(
259+
String tenantId,
260+
String docId,
261+
String err) {
262+
263+
shardedDocumentWriteDao.updateLastError(
264+
tenantId,
265+
docId,
266+
"PUBLISH_FAILED: " + err
267+
);
259268
}
260269

261270
public List<ChunkSearchDao.ChunkHit> semanticSearchChunks(
@@ -274,19 +283,9 @@ public List<ChunkSearchDao.ChunkHit> semanticSearchChunks(
274283
);
275284
}
276285

277-
public boolean claimProcessingLease(String docId, String workerId) {
278-
return documentWriteDao.claimProcessingLease(docId, workerId);
279-
}
280286

281-
public void markReadyDb(String docId) {
282-
int updated = documentWriteDao.markReady(docId);
283287

284-
if (updated != 1) {
285-
throw new IllegalStateException(
286-
"Invalid READY transition for docId=" + docId
287-
);
288-
}
289-
}
288+
290289

291290

292291
public int markRetryCycleExhausted(

src/main/java/com/veriprotocol/springAI/core/ShardedDocumentWriteDao.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@ public Optional<ExistingDocument> findByTenantAndRequestId(
7676
return rows.stream().findFirst();
7777
}
7878

79+
public int updateLastError(
80+
String tenantId,
81+
String docId,
82+
String error) {
83+
84+
JdbcTemplate jdbc =
85+
shardJdbcRouter.jdbcFor(tenantId);
86+
87+
return jdbc.update("""
88+
UPDATE documents
89+
SET last_error = ?,
90+
updated_at = now()
91+
WHERE tenant_id = ?
92+
AND id = ?
93+
""",
94+
error,
95+
tenantId,
96+
docId
97+
);
98+
}
99+
79100
public record ExistingDocument(
80101
String id,
81102
String contentHash) {}

src/main/java/com/veriprotocol/springAI/persistence/DocumentReadDao.java

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,7 @@ public DocumentStatusDto mapRow(ResultSet rs, int rowNum) throws SQLException {
4747

4848
// Internal worker lookup.
4949
// Safe because document IDs are globally unique and this is not user-facing.
50-
public Optional<DocumentStatusDto> findStatusById(String id) {
5150

52-
var list = jdbcTemplate.query("""
53-
SELECT id, status,
54-
COALESCE(retry_count, 0) AS retry_count,
55-
created_at, updated_at,
56-
last_error, worker_id,
57-
processing_started_at, next_retry_at
58-
FROM documents
59-
WHERE id = ?
60-
""",
61-
MAPPER,
62-
id
63-
);
64-
65-
return list.stream().findFirst();
66-
}
6751
public Optional<DocumentStatusDto> findStatusByTenantAndId(
6852
String tenantId,
6953
String id) {
@@ -89,59 +73,17 @@ public Optional<DocumentStatusDto> findStatusByTenantAndId(
8973
return list.stream().findFirst();
9074
}
9175

92-
public List<RetryableDoc> findRetryableFailedDocs(
93-
int limit,
94-
int maxRetries) {
9576

96-
return jdbcTemplate.query("""
97-
SELECT tenant_id, id
98-
FROM documents
99-
WHERE status = 'FAILED'
100-
AND retry_count < ?
101-
AND (next_retry_at IS NULL OR next_retry_at <= now())
102-
ORDER BY updated_at ASC
103-
LIMIT ?
104-
""",
105-
(rs, rowNum) -> new RetryableDoc(
106-
rs.getString("tenant_id"),
107-
rs.getString("id")
108-
),
109-
maxRetries,
110-
limit
111-
);
112-
}
11377
public record RetryableDoc(
11478
String tenantId,
11579
String docId
11680
) {}
11781

118-
public int resetFailedToPending(String docId) {
119-
return jdbcTemplate.update("""
120-
UPDATE documents
121-
SET status = 'PENDING',
122-
last_error = NULL,
123-
processing_started_at = NULL,
124-
worker_id = NULL,
125-
updated_at = now()
126-
WHERE id = ?
127-
AND status = 'FAILED'
128-
""", docId);
129-
}
82+
13083

13184
public record DocPayload(String id, String tenantId, String text, String contentHash) {}
13285

133-
public DocPayload loadDocPayload(String id) {
134-
return jdbcTemplate.queryForObject("""
135-
SELECT id, tenant_id, text, content_hash
136-
FROM documents
137-
WHERE id = ?
138-
""", (rs, rowNum) -> new DocPayload(
139-
rs.getString("id"),
140-
rs.getString("tenant_id"),
141-
rs.getString("text"),
142-
rs.getString("content_hash")
143-
), id);
144-
}
86+
14587

14688
public List<String> findOldPendingDocIdsForTenant(
14789
String tenantId,

src/main/java/com/veriprotocol/springAI/persistence/DocumentSearchDao.java

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/main/java/com/veriprotocol/springAI/persistence/DocumentVectorDao.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/com/veriprotocol/springAI/persistence/DocumentWriteDao.java

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -78,104 +78,6 @@ public int updateStatusAndError(String docId, DocumentStatus status, String msg)
7878
}
7979

8080

81-
/* public boolean claimProcessingLease(String docId, String workerId) {
82-
var rows = jdbcTemplate.queryForList("""
83-
INSERT INTO documents (id, status, worker_id, processing_started_at, retry_count, updated_at)
84-
VALUES (?, 'PROCESSING', ?, now(), 0, now())
85-
ON CONFLICT (id) DO UPDATE
86-
SET status = 'PROCESSING',
87-
worker_id = EXCLUDED.worker_id,
88-
processing_started_at = now(),
89-
updated_at = now()
90-
WHERE documents.status IN ('PENDING', 'FAILED')
91-
RETURNING id
92-
""", docId, workerId);
93-
94-
return !rows.isEmpty();
95-
}*/
96-
97-
98-
public boolean claimProcessingLease(String docId, String workerId) {
99-
100-
var rows = jdbcTemplate.queryForList("""
101-
UPDATE documents
102-
SET status = 'PROCESSING',
103-
worker_id = ?,
104-
processing_started_at =
105-
CASE
106-
WHEN status = 'PROCESSING'
107-
THEN processing_started_at
108-
ELSE now()
109-
END,
110-
updated_at = now()
111-
WHERE id = ?
112-
AND (
113-
status IN ('PENDING', 'FAILED')
114-
OR
115-
(status = 'PROCESSING' AND worker_id = ?)
116-
)
117-
RETURNING id
118-
""",
119-
String.class,
120-
workerId,
121-
docId,
122-
workerId
123-
);
124-
125-
return !rows.isEmpty();
126-
}
127-
128-
public int markReady(String docId) {
129-
return jdbcTemplate.update("""
130-
UPDATE documents
131-
SET status = 'READY',
132-
last_error = NULL,
133-
next_retry_at = NULL,
134-
processing_started_at = NULL,
135-
worker_id = NULL,
136-
updated_at = now()
137-
WHERE id = ?
138-
AND status = 'PROCESSING'
139-
""", docId);
140-
}
141-
142-
public String insertPendingIfAbsent(
143-
String id,
144-
String tenantId,
145-
String requestId,
146-
String text,
147-
String contentHash) {
148-
149-
var ids = jdbcTemplate.queryForList("""
150-
INSERT INTO documents (
151-
id,
152-
tenant_id,
153-
request_id,
154-
text,
155-
content_hash,
156-
status,
157-
retry_count,
158-
created_at,
159-
updated_at
160-
)
161-
VALUES (?, ?, ?, ?, ?, 'PENDING', 0, now(), now())
162-
ON CONFLICT (tenant_id, request_id) DO NOTHING
163-
RETURNING id
164-
""",
165-
String.class,
166-
id,
167-
tenantId,
168-
requestId,
169-
text,
170-
contentHash
171-
);
172-
173-
return ids.isEmpty() ? null : ids.get(0);
174-
}
175-
176-
177-
178-
17981

18082

18183
public int markStuckProcessingAsFailed(int minutes) {
@@ -192,23 +94,7 @@ public int markStuckProcessingAsFailed(int minutes) {
19294
AND processing_started_at < now() - (? || ' minutes')::interval
19395
""", minutes);
19496
}
195-
196-
197-
198-
public int resetFailedToPending(String docId) {
199-
return jdbcTemplate.update("""
200-
UPDATE documents
201-
SET status = 'PENDING',
202-
last_error = NULL,
203-
next_retry_at = NULL,
204-
processing_started_at = NULL,
205-
worker_id = NULL,
206-
updated_at = now()
207-
WHERE id = ?
208-
AND status = 'FAILED'
209-
AND (next_retry_at IS NULL OR next_retry_at <= now())
210-
""", docId);
211-
}
97+
21298

21399

214100
public int forceToPending(

0 commit comments

Comments
 (0)