Harden archive bot for production; exempt container egress in edge firewall
- archive_sync_state keyed by room per migration 029 (drop synthetic id cursor) - putStaging buffers the stream and sends content-length (oCIS rejects chunked) - mimeClass passthrough from sniffed payload - edge-firewall: RETURN docker-bridge ingress before the CF-range catch-all so container egress (Matrix/R2/platform) survives the 80/443 source filter - files scaffold: keep the ocdav data-gateway hop on-loopback
This commit is contained in:
parent
23bd4dd5ad
commit
2cb77ae6b4
9 changed files with 211 additions and 38 deletions
|
|
@ -6,7 +6,7 @@ import { classifyEvent, type AttachmentWork, type MatrixEvent, type RoomEncrypti
|
|||
import { PermanentArchiveError } from "./inspector.js";
|
||||
import { claimKey, replyTxnId } from "./keys.js";
|
||||
import { MatrixHttpError, type MatrixPort } from "./matrix.js";
|
||||
import type { ArchiveStore } from "./store.js";
|
||||
import type { ArchiveStore, RoomCursorTarget } from "./store.js";
|
||||
|
||||
export interface BatchResult {
|
||||
/** True when the sync cursor was durably advanced past this batch. */
|
||||
|
|
@ -61,6 +61,7 @@ export class ArchiveProcessor {
|
|||
/** Committed claims whose single reply has not been delivered yet (key → safe name). */
|
||||
private readonly unsentReplies = new Map<string, string>();
|
||||
private readonly byRoom: Map<string, RoomMapping>;
|
||||
private readonly cursorRooms: RoomCursorTarget[];
|
||||
private readonly workspaceIds: string[];
|
||||
|
||||
constructor(
|
||||
|
|
@ -72,11 +73,12 @@ export class ArchiveProcessor {
|
|||
private readonly now: () => Date = () => new Date(),
|
||||
) {
|
||||
this.byRoom = new Map(mappings.map((m) => [m.roomId, m]));
|
||||
this.cursorRooms = mappings.map((m) => ({ roomId: m.roomId, workspaceId: m.workspaceId }));
|
||||
this.workspaceIds = [...new Set(mappings.map((m) => m.workspaceId))];
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
this.cursor = await this.store.loadCursor(this.workspaceIds);
|
||||
this.cursor = await this.store.loadCursor(this.cursorRooms);
|
||||
}
|
||||
|
||||
async health(): Promise<HealthSnapshot> {
|
||||
|
|
@ -115,7 +117,7 @@ export class ArchiveProcessor {
|
|||
}
|
||||
|
||||
if (retryAt !== null) return { advanced: false, retryAt };
|
||||
await this.store.saveCursor(this.workspaceIds, sync.nextBatch);
|
||||
await this.store.saveCursor(this.cursorRooms, sync.nextBatch);
|
||||
this.cursor = sync.nextBatch;
|
||||
return { advanced: true, retryAt: null };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue