-
Notifications
You must be signed in to change notification settings - Fork 217
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rewrite unarchivePatches so if blob is gone/broken, timetravel is aut…
…omatically reset and admins get a message - hopefully! This is hard to test in dev mode.
- Loading branch information
1 parent
22f3d20
commit 6528e5f
Showing
6 changed files
with
125 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import getLogger from "@cocalc/backend/logger"; | ||
import type { PostgreSQL } from "./types"; | ||
import getPool from "@cocalc/database/pool"; | ||
import { callback2 } from "@cocalc/util/async-utils"; | ||
|
||
const logger = getLogger("database:blobs"); | ||
|
||
export async function unarchivePatches({ | ||
db, | ||
string_id, | ||
}: { | ||
db: PostgreSQL; | ||
string_id: string; | ||
}) { | ||
const dbg = (...args) => { | ||
logger.debug("unarchivePatches", { string_id }, ...args); | ||
}; | ||
dbg(); | ||
|
||
const pool = getPool(); | ||
const { rows } = await pool.query( | ||
"SELECT archived, project_id, path FROM syncstrings WHERE string_id=$1", | ||
[string_id], | ||
); | ||
if (rows.length == 0) { | ||
throw Error(`no syncstring with id ${string_id}`); | ||
} | ||
const uuid = rows[0].archived; | ||
if (!uuid) { | ||
dbg("it is not archived"); | ||
return; | ||
} | ||
dbg("download blob"); | ||
let blob; | ||
let error = ""; | ||
try { | ||
blob = await callback2(db.get_blob, { uuid }); | ||
} catch (err) { | ||
dbg(`WARNING -- unable to get blob with id ${uuid}`, err); | ||
blob = null; | ||
error = `${err}`; | ||
} | ||
if (blob == null) { | ||
if (db.adminAlert != null) { | ||
dbg("NONFATAL ERROR -- blob is GONE!"); | ||
// Instead of giving up, we basically give up on the syncstring history, and also | ||
// send a message to admins to look into it. This is better than completely blocking | ||
// access to the file to the user, especially since they have the file on disk along | ||
// with filesystem snapshots. Also this *should* never happen. I'm writing this because | ||
// I switched .compute-servers.syncdb between ephemeral and not, which seems to have | ||
// broken some of these, and I think we also hit this once or twice before. | ||
await db.adminAlert({ | ||
subject: `missing TimeTravel history for path='${rows[0].path}'`, | ||
body: `The blob with TimeTravel history for editing path='${rows[0].path}' is missing. | ||
Instead of breaking things for the user, things might work, but with the history reset. That said, | ||
an admin should look into this. | ||
- project_id='${rows[0].project_id}' | ||
- path='${rows[0].path}' | ||
- string_id='${string_id}' | ||
- error='${error}' | ||
`, | ||
}); | ||
} else { | ||
// can't even alert admins | ||
dbg("FATAL ERROR -- blob is gone (unable to alert admins)"); | ||
throw Error("blob is gone"); | ||
} | ||
} else { | ||
dbg("extract blob"); | ||
const patches = JSON.parse(blob); | ||
await callback2(db.import_patches, { patches }); | ||
} | ||
|
||
dbg("update syncstring to indicate that patches are now available"); | ||
await pool.query("UPDATE syncstrings SET archived=NULL WHERE string_id=$1", [ | ||
string_id, | ||
]); | ||
if (blob != null) { | ||
dbg("delete blob, which is now no longer needed"); | ||
await callback2(db.delete_blob, { uuid }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters