fix(preview): Status bleibt bei Runner-Builds, dev-Label, Abgleich mit dem Runner, Längenkürzung
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
19cd8f90ce
commit
b7cbe3aa38
8 files changed
+396
-15
No files matched your search
@@ -0,0 +1,77 @@
|
||||
// R18: Abgleich der Preview-Zustaende mit dem Runner (alle 2 Minuten, nur mit PREVIEW_RUNNER=on).
|
||||
// (a) 'building' ohne laufenden Verfolger und aelter als 70 Minuten => 'failed'
|
||||
// (b) Dev-Projekte: Zustand laut Runner (laeuft => online/starting, sonst sleeping); Modus 'off' bleibt unberuehrt
|
||||
// (c) Dev-Spezifikationen, die der Runner nicht kennt (z. B. nach Neustart), erneut hinterlegen
|
||||
// Wirft nie: Fehler werden protokolliert und im Ergebnis gemeldet.
|
||||
import { config } from '../config.js'
|
||||
import { listDocuments, updateDocument, Query } from './appwriteAdmin.js'
|
||||
import * as runnerClient from './previewRunnerClient.js'
|
||||
import { hasLiveFollower, registerDevRound } from './previewDeploy.js'
|
||||
|
||||
export const STALE_BUILD_MS = 70 * 60 * 1000
|
||||
const STALE_TEXT = 'Status unbekannt – bitte neu bauen'
|
||||
|
||||
const isDev = (d) => String(d.previewDetected || '').startsWith('dev')
|
||||
|
||||
export async function reconcilePreviews({ now = Date.now() } = {}) {
|
||||
if (!config.previewRunner.enabled) return { skipped: true }
|
||||
const result = { staleFailed: 0, stateUpdated: 0, reregistered: 0 }
|
||||
let docs
|
||||
try {
|
||||
docs = await listDocuments(config.collections.websiteProjects, [
|
||||
Query.equal('previewState', ['building', 'sleeping', 'starting', 'online']),
|
||||
Query.limit(500),
|
||||
])
|
||||
} catch (err) {
|
||||
console.error('[previewReconcile] Projekte nicht lesbar:', err.message)
|
||||
return { ...result, error: err.message }
|
||||
}
|
||||
|
||||
const patch = async (doc, data) => {
|
||||
try { await updateDocument(config.collections.websiteProjects, doc.$id, data); return true } catch (err) {
|
||||
console.error('[previewReconcile] Update fehlgeschlagen:', err.message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// (a)
|
||||
for (const doc of docs) {
|
||||
if (doc.previewState !== 'building' || !doc.repoFullName) continue
|
||||
if (hasLiveFollower(doc.repoFullName)) continue
|
||||
const since = Date.parse(doc.$updatedAt || doc.$createdAt || '')
|
||||
if (!Number.isFinite(since) || now - since <= STALE_BUILD_MS) continue
|
||||
if (await patch(doc, { previewState: 'failed', previewError: STALE_TEXT })) result.staleFailed++
|
||||
}
|
||||
|
||||
// (b) + (c)
|
||||
const devDocs = docs.filter((d) => isDev(d) && d.previewMode !== 'off' && d.previewState !== 'building' && d.subdomain)
|
||||
if (!devDocs.length) return result
|
||||
let st
|
||||
try { st = await runnerClient.status() } catch (err) {
|
||||
console.error('[previewReconcile] Runner-Status nicht abrufbar:', err.message)
|
||||
return { ...result, error: err.message }
|
||||
}
|
||||
const entries = new Map((st?.dev || []).map((e) => [e.sub, e]))
|
||||
const known = new Set([...(st?.known || []), ...entries.keys()])
|
||||
const unknown = []
|
||||
for (const doc of devDocs) {
|
||||
const entry = entries.get(doc.subdomain)
|
||||
const want = entry?.state === 'online' ? 'online' : entry?.state === 'starting' ? 'starting' : 'sleeping'
|
||||
if (doc.previewState !== want && (await patch(doc, { previewState: want }))) result.stateUpdated++
|
||||
if (!known.has(doc.subdomain)) unknown.push(doc)
|
||||
}
|
||||
if (unknown.length) {
|
||||
try { await registerDevRound(unknown); result.reregistered = unknown.length } catch (err) {
|
||||
console.error('[previewReconcile] Registrierung fehlgeschlagen:', err.message)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Fuer setInterval: nie werfen. */
|
||||
export function runReconcile() {
|
||||
return reconcilePreviews().catch((err) => {
|
||||
console.error('[previewReconcile] Lauf fehlgeschlagen:', err.message)
|
||||
return { error: err.message }
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user