feat(server): blob reconciliation (#15165)

#### PR Dependency Tree


* **PR #15165** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added automated backend maintenance for missing blob metadata
backfill, document-to-blob reference rebuilding, and unreferenced blob
cleanup planning/execution.
* Introduced scheduled batch processing (workspace-paged) and paginated
object-storage listing.
* **Bug Fixes**
* Improved reliability of object-storage reads by treating expected “not
found” results as non-errors.
* Strengthened blob/expired cleanup flows with runtime-driven batching
and reduced coupling to metadata synchronization.
* **Tests**
* Expanded unit and e2e coverage for partial blob metadata and updated
runtime/job cleanup test assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-06-29 00:02:38 +08:00
committed by GitHub
parent 4a7c931eca
commit 0a422aa158
42 changed files with 2494 additions and 264 deletions

View File

@@ -1,13 +1,22 @@
/* auto-generated by NAPI-RS */
/* eslint-disable */
declare const _default: typeof import('./index')
export default _default
export declare class BackendRuntime {
planUnreferencedWorkspaceBlobs(workspaceId: string, gracePeriodDays: number, limit: number): Promise<RuntimeBlobCleanupPlanResult>
executeBlobCleanupCandidates(runId: string, gracePeriodDays: number, limit: number): Promise<RuntimeBlobCleanupExecuteResult>
completeBlobUpload(workspaceId: string, key: string, expectedSize: number, expectedMime: string): Promise<RuntimeBlobCompleteResult>
completeFsBlobUpload(root: string, bucket: string, workspaceId: string, key: string, expectedSize: number, expectedMime: string): Promise<RuntimeBlobCompleteResult>
cleanupExpiredPendingBlobs(cutoffMs: number, limit: number): Promise<RuntimeBlobCleanupResult>
releaseDeletedBlobs(workspaceId: string, limit: number): Promise<RuntimeBlobCleanupResult>
backfillMissingBlobMetadata(workspaceId: string | undefined | null, limit: number): Promise<RuntimeBlobMetadataBackfillResult>
acquireCoordinationLease(key: string, owner: string, ttlMs: number): Promise<CoordinationLeaseGrant | null>
releaseCoordinationLease(key: string, owner: string, fencingToken: bigint | number): Promise<boolean>
renewCoordinationLease(key: string, owner: string, fencingToken: bigint | number, ttlMs: number): Promise<boolean>
rebuildDocBlobRefs(workspaceId: string, docId: string): Promise<RuntimeDocBlobRefsResult>
rebuildWorkspaceDocBlobRefs(workspaceId: string, limit: number): Promise<RuntimeDocBlobRefsResult>
/**
* Merge pending doc updates with y-octo and persist the merged snapshot.
*
@@ -816,6 +825,25 @@ export declare function resolveEntitlementV1(input: ResolveEntitlementInput): Re
export declare function runNativeActionRecipePreparedStream(input: ActionRuntimeInput, callback: ((err: Error | null, arg: string) => void)): LlmStreamHandle
export interface RuntimeBlobCleanupExecuteResult {
scannedCandidates: number
deletedObjects: number
deletedMetadata: number
skippedStillReferenced: number
failed: number
workspaceIds: Array<string>
}
export interface RuntimeBlobCleanupPlanResult {
runId?: string
scannedBlobs: number
candidatesMarked: number
protectedByDocRefs: number
protectedByMetadata: number
protectedByOtherRefs: number
nextCursor?: string
}
export interface RuntimeBlobCleanupResult {
scanned: number
deleted: number
@@ -831,12 +859,32 @@ export interface RuntimeBlobCompleteResult {
lastModifiedMs?: number
}
export interface RuntimeBlobMetadataBackfillResult {
scannedObjects: number
headedObjects: number
upsertedMetadata: number
skippedExisting: number
skippedWorkspaceMissing: number
failed: number
nextCursor?: string
workspaceIds: Array<string>
}
export interface RuntimeByokLocalLeaseRecord {
leaseId: string
payload: any
expiresAtMs: number
}
export interface RuntimeDocBlobRefsResult {
scannedDocs: number
parsedDocs: number
refsWritten: number
refsDeleted: number
failedDocs: number
nextCursor?: string
}
export interface RuntimeDocCompactionResult {
leaseAcquired: boolean
merged: boolean