File size: 1,624 Bytes
a4abfcf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bfb9f20
a4abfcf
 
 
 
 
 
 
 
 
 
 
bfb9f20
a4abfcf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { resolve } from "node:path";

function buildAdminConnectionString(port: number) {
  return `postgres://paperclip:paperclip@127.0.0.1:${port}/postgres`;
}

function normalizePath(value: string) {
  return resolve(value);
}

export async function resolveReusableEmbeddedPostgresPort(input: {
  dataDir: string;
  configuredPort: number;
  runningPid: number | null;
  runningPort: number | null;
  getPostgresDataDirectory: (connectionString: string) => Promise<string | null>;
  ensurePostgresDatabase: (connectionString: string, databaseName: string) => Promise<unknown>;
  removePidFile: () => void;
  logWarn?: (message: string) => void;
}): Promise<number | null> {
  if (!input.runningPid) return null;

  const candidatePort = input.runningPort ?? input.configuredPort;
  const connectionString = buildAdminConnectionString(candidatePort);

  try {
    const actualDataDir = await input.getPostgresDataDirectory(connectionString);
    if (!actualDataDir || normalizePath(actualDataDir) !== normalizePath(input.dataDir)) {
      input.logWarn?.(
        `Embedded PostgreSQL pid file pointed at a reachable postgres on port ${candidatePort}, but its data dir did not match ${input.dataDir}; ignoring stale pid file.`,
      );
      input.removePidFile();
      return null;
    }

    await input.ensurePostgresDatabase(connectionString, "paperclip");
    return candidatePort;
  } catch {
    input.logWarn?.(
      `Embedded PostgreSQL pid file pointed at pid ${input.runningPid}, but port ${candidatePort} was not reusable; ignoring stale pid file.`,
    );
    input.removePidFile();
    return null;
  }
}