-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdbStart.mjs
67 lines (62 loc) · 1.52 KB
/
dbStart.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// @ts-check
import pg from "pg";
import runAll from "npm-run-all";
import "dotenv/config";
/** @param {string} url */
export async function dbTest(
url,
{ minDelay = 50, maxTries = Infinity, maxDelay = 30000, verbose = true } = {},
) {
const pool = new pg.Pool({
connectionString: process.env.DATABASE_URL,
connectionTimeoutMillis: 3000,
});
let attempts = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
try {
const { rows: result } = await pool.query('select true as "test"');
if (result[0].test === true) break;
} catch (e) {
if (e.code === "28P01") {
await pool.end();
throw e;
}
attempts++;
if (attempts > maxTries) {
await pool.end();
throw e;
}
if (verbose)
console.log(
`Database is not ready yet (attempt ${attempts}): ${e.message}`,
);
const delay = Math.min(
Math.floor((minDelay * 1.8 ** attempts) / 2),
maxDelay,
);
await new Promise(res => setTimeout(() => res(), delay));
}
}
pool.end();
return true;
}
const runAllOpts = {
stdin: process.stdin,
stdout: process.stdout,
stderr: process.stderr,
silent: true,
};
try {
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL is not set");
}
await runAll(["db:start"], runAllOpts);
await dbTest(process.env.DATABASE_URL, {
maxTries: 8,
verbose: false,
});
} catch (e) {
console.error(e.message);
runAll(["setup"], runAllOpts).catch(console.error);
}