fix(studio): review round 2 - a conversion that fails after its commit recovers without a restart
- The convert job reloads the course on success and on failure, so learners get the intact import (rolled back) or the published studio course, never a course whose folder moved away. - POST /convert on a course with an incomplete conversion (.converting-<id>, staging or retired folders) queues a job that recovers and finishes it instead of answering 409; the studio page shows "Conversion incomplete" with Retry for the owner. - The 409 for pending import jobs names their kinds and ids; the dead withLock in git.ts is gone; the dot-folder discovery rule is documented in docs/operations.md and spec section 5. - Route tests (SQLite and Postgres) inject a failed cross-filesystem copy, a checksum mismatch and a pre-commit failure. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
771d755da4
commit
f02e30450c
@@ -55,15 +55,3 @@ export async function gitOk(cwd: string, args: string[], who?: Identity): Promis
|
||||
export function splitZ(out: string): string[] {
|
||||
return out.split("\0").filter(Boolean);
|
||||
}
|
||||
|
||||
const locks = new Map<string, Promise<unknown>>();
|
||||
|
||||
/** Serialises git work per key (the course's bare repo path) across every store instance in the process. */
|
||||
export function withLock<T>(key: string, fn: () => Promise<T>): Promise<T> {
|
||||
const prev = locks.get(key) ?? Promise.resolve();
|
||||
const next = prev.then(fn, fn);
|
||||
const tail = next.catch(() => {});
|
||||
locks.set(key, tail);
|
||||
tail.then(() => { if (locks.get(key) === tail) locks.delete(key); });
|
||||
return next;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user