62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
|
|
import assert from "node:assert/strict";
|
||
|
|
import { execFile } from "node:child_process";
|
||
|
|
import { promisify } from "node:util";
|
||
|
|
|
||
|
|
const execute = promisify(execFile);
|
||
|
|
|
||
|
|
export function latch() {
|
||
|
|
let release: () => void = () => {
|
||
|
|
throw new Error("Barrera sin inicializar.");
|
||
|
|
};
|
||
|
|
|
||
|
|
const promise = new Promise<void>((resolve) => {
|
||
|
|
release = resolve;
|
||
|
|
});
|
||
|
|
|
||
|
|
return { promise, release };
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function waitBarrier(promise: Promise<void>) {
|
||
|
|
let timer: NodeJS.Timeout | undefined;
|
||
|
|
|
||
|
|
try {
|
||
|
|
await Promise.race([
|
||
|
|
promise,
|
||
|
|
new Promise<never>((_resolve, reject) => {
|
||
|
|
timer = setTimeout(
|
||
|
|
() => reject(new Error("No se alcanzó la barrera transaccional.")),
|
||
|
|
15000
|
||
|
|
);
|
||
|
|
}),
|
||
|
|
]);
|
||
|
|
} finally {
|
||
|
|
clearTimeout(timer);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Observa una espera real de InnoDB fuera del pool probado; no vuelca credenciales del contenedor. */
|
||
|
|
export async function waitCatalogLock(container: string) {
|
||
|
|
assert.match(container, /^metis-scope-test-[a-f0-9]+$/u);
|
||
|
|
const deadline = Date.now() + 10000;
|
||
|
|
|
||
|
|
while (Date.now() < deadline) {
|
||
|
|
const { stdout } = await execute(
|
||
|
|
"docker",
|
||
|
|
[
|
||
|
|
"exec",
|
||
|
|
container,
|
||
|
|
"sh",
|
||
|
|
"-c",
|
||
|
|
'MYSQL_PWD="$MARIADB_ROOT_PASSWORD" mariadb -uroot -N -B --execute="SELECT COUNT(*) FROM information_schema.INNODB_LOCK_WAITS w JOIN information_schema.INNODB_LOCKS b ON b.lock_id=w.blocking_lock_id WHERE b.lock_table LIKE \'%resource_catalogs%\'"',
|
||
|
|
],
|
||
|
|
{ timeout: 5000 }
|
||
|
|
);
|
||
|
|
|
||
|
|
if (Number(stdout.trim()) > 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
await new Promise<void>((resolve) => setImmediate(resolve));
|
||
|
|
}
|
||
|
|
throw new Error("No se observó la espera de InnoDB esperada.");
|
||
|
|
}
|